Skip to content

fix: upgrade brace-expansion to 5.0.7, 1.1.16, 2.1.2 (CVE-2026-13149) - #79

Open
anupamme wants to merge 1 commit into
FortiumPartners:mainfrom
anupamme:fix-repo-ensemble-cve-2026-13149-brace-expansion
Open

fix: upgrade brace-expansion to 5.0.7, 1.1.16, 2.1.2 (CVE-2026-13149)#79
anupamme wants to merge 1 commit into
FortiumPartners:mainfrom
anupamme:fix-repo-ensemble-cve-2026-13149-brace-expansion

Conversation

@anupamme

@anupamme anupamme commented Aug 1, 2026

Copy link
Copy Markdown

Summary

Upgrade brace-expansion from 2.0.2 to 5.0.7, 1.1.16, 2.1.2 to fix CVE-2026-13149.

Vulnerability

Field Value
ID CVE-2026-13149
Severity HIGH
Scanner trivy
Rule CVE-2026-13149
File package-lock.json (dependency: brace-expansion)
Assessment Present in dependency tree, not confirmed reachable

Description: brace-expansion: Brace-expansion: Denial of Service due to exponential-time complexity

Evidence

Scanner confirmation: trivy rule CVE-2026-13149 flagged this pattern.

Changes

  • package.json
  • package-lock.json

Behavior Preservation

The change is scoped to 2 files on the vulnerable path; it only tightens handling of untrusted input and leaves valid inputs unaffected.


This change addresses a pattern flagged by static analysis. The code path handles user-influenced input and the fix reduces the attack surface against both manual and automated exploitation.


Automated security fix by OrbisAI Security

Summary by CodeRabbit

  • Chores
    • Added MIT license metadata.
    • Updated package configuration to use a specific dependency version for improved consistency.

Automated dependency upgrade by OrbisAI Security
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The package metadata now declares the MIT license and pins brace-expansion to version 2.1.2 as both a direct dependency and an npm override.

Changes

Package metadata and dependency pinning

Layer / File(s) Summary
License and dependency declarations
package.json
Adds the MIT license field, declares brace-expansion at version 2.1.2, and applies an npm override for the same version.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Suggested reviewers: ldangelo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the brace-expansion upgrade and the security vulnerability addressed by the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request has been flagged as potential spam (promotional) by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package.json`:
- Around line 48-49: Update the package.json overrides configuration to scope
brace-expansion version 2.1.2 under the specific dependent package that requires
it, rather than applying it globally. Preserve the existing lockfile resolutions
of 5.0.7 and 1.1.16 for the other dependency paths.
- Around line 47-53: Resolve the validation errors reported for
marketplace.json, then run npm run validate and address any remaining failures
until the command exits successfully.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7cfa6aab-5d01-4757-84b3-9862a33cc116

📥 Commits

Reviewing files that changed from the base of the PR and between 8535af9 and fe4bffe.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • package.json

Comment thread package.json
Comment on lines +47 to +53
"license": "MIT",
"overrides": {
"brace-expansion": "2.1.2"
},
"dependencies": {
"brace-expansion": "2.1.2"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

npm run validate

Repository: FortiumPartners/ensemble

Length of output: 1041


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package scripts =="
node -e 'const p=require("./package.json"); console.log(JSON.stringify(p.scripts,null,2)); console.log(JSON.stringify(Object.keys(p.dependencies||{}).filter(k=>k.toLowerCase().includes("yaml") || k.toLowerCase().includes("json")), null, 2));'

echo
echo "== validate-all.js outline/size =="
wc -l scripts/validate-all.js
sed -n '1,220p' scripts/validate-all.js

echo
echo "== package.json relevant =="
sed -n '1,90p' package.json

echo
echo "== lockfile brace-expansion and yaml packages =="
python3 - <<'PY'
import json
from pathlib import Path
for name in ["package.json","package-lock.json"]:
    p=Path(name)
    if p.exists():
        data=json.loads(p.read_text())
        print(f"\n--- {name} ---")
        if name=="package-lock.json":
            for key in sorted(data.get("packages",{}).keys()):
                if key in ("","node_modules/brace-expansion","node_modules/yaml","node_modules/@apidevtools/json-schema-ref-parser","node_modules/ajv"):
                    v=data["packages"][key]
                    print(key, v.get("version"), v.get("resolved"), dict(v.get("dependencies",{})), dict(v.get("devDependencies",{})) if key!="") else "")
PY

echo
echo "== lockfile npm cli command references =="
rg -n '"npm|"command":|"npm run|store-dir|marketplace\.json|validate' package-lock.json scripts package.json

Repository: FortiumPartners/ensemble

Length of output: 6956


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

for name in ["package.json","package-lock.json"]:
    p=Path(name)
    if p.exists():
        data=json.loads(p.read_text())
        print(f"\n--- {name} ---")
        if name=="package-lock.json":
            for key in ("","node_modules/brace-expansion","node_modules/yaml","node_modules/@apidevtools/json-schema-ref-parser","node_modules/ajv","node_modules/ajv-cli","node_modules/ajv-formats"):
                if key in data.get("packages", {}):
                    v=data["packages"][key]
                    print(key, "version=", v.get("version"), "resolved=", v.get("resolved"), "bin=", v.get("bin"), "deps=", v.get("dependencies"), "devDeps=", v.get("devDependencies"))
PY

echo
echo "== npm lockfile integrity summary =="
if [ -f package-lock.json ]; then
  node -e ' const d=require("./package-lock.json"); const pk=d.packages; console.log("rootContentHash=", Object.keys(d).includes("contentHash")). "packages=", Object.keys(pk).length; console.log(Object.keys(pk).filter(k=>k.startsWith("node_modules/")&&k.split("/").length===2).slice(0,50).join("\\n")); '
else
  echo "package-lock.json missing"
fi

echo
echo "== ajv schema references =="
cat -n schemas/marketplace-schema.json | sed -n '1,220p'

echo
echo "== marketplace summary =="
python3 - <<'PY'
import json
from pathlib import Path
p=Path("marketplace.json")
if p.exists():
    data=json.loads(p.read_text())
    keys=sorted(data.keys())
    print("top_keys=", keys)
    if "plugins" in data:
        print("plugin_count=", len(data["plugins"]))
        for i, plugin in enumerate(data["plugins"][:5]):
            print(f"\nplugin {i}")
            for k,v in plugin.items():
                if k in ("name","version","displayName","description","tags","files","settings","capabilities","environment"):
                    print(f"  {k}=", v if not isinstance(v,list) else f"[len={len(v)}]")
PY

echo
echo "== ajv-cli and js-yaml presence in lockfile/installed? =="
node - <<'JS'
const { execSync } = require('child_process');
try { execSync('npm view ajv-cli dist.tarball version --json', {stdio:'inherit'}); }
catch(e) { console.log("npm view failed:", e.message); }
try { execSync('npm view js-yaml dist.tarball version --json', {stdio:'inherit'}); }
catch(e) { console.log("npm view failed:", e.message); }
JS

Repository: FortiumPartners/ensemble

Length of output: 2138


Run, then pass npm run validate before merge.

The required pre-submission validation currently fails, with marketplace.json still marked invalid. Resolve the validation errors and rerun this command until it exits successfully.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 47 - 53, Resolve the validation errors reported
for marketplace.json, then run npm run validate and address any remaining
failures until the command exits successfully.

Source: Coding guidelines

Comment thread package.json
Comment on lines +48 to +49
"overrides": {
"brace-expansion": "2.1.2"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

npm ls brace-expansion --all || true
npm explain brace-expansion
jq -r '
  .packages
  | to_entries[]
  | select(.key | endswith("/brace-expansion"))
  | [.key, .value.version]
  | `@tsv`
' package-lock.json

Repository: FortiumPartners/ensemble

Length of output: 1015


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- package.json relevant section ---\n'
cat -n package.json | sed -n '1,80p'

printf '\n--- package-lock brace-expansion entries ---\n'
jq -r '
  .packages
  | to_entries[]
  | select(.key | endswith("/brace-expansion"))
  | [.key, .value.version]
  | `@tsv`
' package-lock.json 2>/dev/null || true

printf '\n--- package.json overrides field ---\n'
jq '.overrides' package.json 2>/dev/null || true

Repository: FortiumPartners/ensemble

Length of output: 253


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- package.json relevant section ---'
cat -n package.json | sed -n '1,80p'

printf '%s\n' ''
printf '%s\n' '--- package-lock brace-expansion entries ---'
jq -r '
  .packages
  | to_entries[]
  | select(.key | test("/brace-expansion$"))
  | [.key, .value.version]
  | `@tsv`
' package-lock.json 2>/dev/null || true

printf '%s\n' ''
printf '%s\n' '--- package.json overrides field ---'
jq '.overrides' package.json 2>/dev/null || true

Repository: FortiumPartners/ensemble

Length of output: 2714


Scope the brace-expansion override by dependency path.

The root-level "brace-expansion": "2.1.2" override forces every dependency path to that version. Scope the override by the package that needs brace-expansion 2.1.2, and preserve the separate 5.0.7 and 1.1.16 lockfile resolutions for the other dependency paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 48 - 49, Update the package.json overrides
configuration to scope brace-expansion version 2.1.2 under the specific
dependent package that requires it, rather than applying it globally. Preserve
the existing lockfile resolutions of 5.0.7 and 1.1.16 for the other dependency
paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant