Skip to content

chore(Yarn): bump vulns for brace-expansion, fast-uri - BED-9133 - #3093

Merged
TheNando merged 1 commit into
mainfrom
BED-9133-vulns
Aug 3, 2026
Merged

TheNando merged 1 commit into
mainfrom
BED-9133-vulns

Conversation

@TheNando

@TheNando TheNando commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

Description

Bump brace-expansions and fast-uri up from vulnerable versions

Motivation and Context

Resolves BED-9133

How Has This Been Tested?

Manually

Types of changes

  • Chore (a change that does not modify the application functionality)

Checklist:

Summary by CodeRabbit

  • Bug Fixes
    • Updated packages to vulnerability-patched versions.
    • Added package configuration to ensure the patched versions are used.

@TheNando TheNando self-assigned this Aug 3, 2026
@TheNando
TheNando requested review from a team as code owners August 3, 2026 21:20
@TheNando TheNando added the dependencies Pull requests that update a dependency file label Aug 3, 2026
@coderabbitai

coderabbitai Bot commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The dependency resolutions update brace-expansion to 5.0.9 and fast-uri to 3.1.5. Yarn configuration preapproves both packages and documents their security advisories.

Changes

Dependency remediation

Layer / File(s) Summary
Patched dependency configuration
.yarnrc.yml, package.json
Yarn preapproves brace-expansion and fast-uri. Dependency resolutions require versions 5.0.9 and 3.1.5. The configuration documents the related security advisories.

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

Possibly related PRs

Suggested reviewers: urangel

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Yarn dependency updates for the vulnerable brace-expansion and fast-uri packages.
Description check ✅ Passed The description covers the change, motivation, ticket, testing method, change type, and checklist, but provides limited testing detail.
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
  • Commit unit tests in branch BED-9133-vulns

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 @.yarnrc.yml:
- Around line 29-31: Update the npmPreapprovedPackages entries for
brace-expansion and fast-uri to exact package-version descriptors, without the
npm: protocol, so preapproval applies only to the patched versions.
🪄 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: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 12a0d54a-3a23-4c7d-8f2b-2a6d0962cfba

📥 Commits

Reviewing files that changed from the base of the PR and between 5088538 and ba1d478.

⛔ Files ignored due to path filters (4)
  • .yarn/cache/brace-expansion-npm-5.0.8-08bf144160-75d2d2ebc8.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/brace-expansion-npm-5.0.9-2717df6b49-d8683d6129.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/fast-uri-npm-3.1.5-39a8d368d6-784bef687c.zip is excluded by !**/.yarn/**, !**/*.zip
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (2)
  • .yarnrc.yml
  • package.json

Comment thread .yarnrc.yml
Comment on lines +29 to +31
npmPreapprovedPackages:
- brace-expansion
- fast-uri

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- .yarnrc.yml ---'
cat -n .yarnrc.yml

printf '%s\n' '--- package manifests containing target packages ---'
rg -n -C 3 '"(brace-expansion|fast-uri)"|brace-expansion|fast-uri' --glob 'package.json' --glob 'yarn.lock' --glob '*.yml' --glob '*.yaml' .

printf '%s\n' '--- Yarn metadata and version references ---'
rg -n -i -C 2 'npmPreapprovedPackages|package gate|preapproved' . --glob '!node_modules' --glob '!build' --glob '!dist'

Repository: SpecterOps/BloodHound

Length of output: 5200


🌐 Web query:

Yarn 4 npmPreapprovedPackages exact package descriptor package-name pattern semantics npmMinimalAgeGate

💡 Result:

In Yarn 4, npmMinimalAgeGate and npmPreapprovedPackages are security features designed to prevent the installation of recently published packages, which may be malicious [1][2][3]. npmMinimalAgeGate This setting restricts the installation of packages to those published at least N days (or specified duration) prior to the current time [1]. It defaults to 1d [1]. It can be bypassed for a single command using the --no-time-gate flag [1]. npmPreapprovedPackages This setting defines an array of packages or patterns that are excluded from the npmMinimalAgeGate check [4][5]. It supports several types of identifiers, utilizing micromatch for glob pattern matching [2][3]: 1. Package Descriptors: You can specify package descriptors (e.g., typescript@^5.0.0) [2][6][3]. 2. Glob Patterns: You can use micromatch glob patterns to match package names or descriptors (e.g., @my-scope/@ or @aws-sdk/) [2][6][3]. 3. Exact Locators: The implementation also supports exact match on package locators, which identify specific versions (e.g., @aws-sdk/types@3.877.0 or @aws-sdk/types@npm:3.877.0) [2][3]. Configuration is performed in the.yarnrc.yml file [4][6]. For example: npmPreapprovedPackages: - "typescript@^5.0.0" - "@my-scope/@*" When evaluating candidates during resolution, the npm semver resolver checks these settings to determine if a package is permitted for installation [2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- Yarn configuration references ---'
rg -n -C 5 'npmPreapprovedPackages|npmMinimalAgeGate' .yarn . --glob '*.cjs' --glob '*.js' --glob '*.json' --glob '*.md' --glob '*.yml' --glob '*.yaml' 2>/dev/null || true

printf '%s\n' '--- Relevant lockfile selectors and resolutions ---'
sed -n '7168,7185p' yarn.lock
sed -n '9418,9434p' yarn.lock

Repository: SpecterOps/BloodHound

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
from pathlib import Path

p = Path(".yarn/releases/yarn-4.13.0.cjs")
text = p.read_text()
needles = [
    "npmPreapprovedPackages",
    'function h0t',
    'function g0t',
]
for needle in needles:
    print(f"--- {needle} ---")
    start = text.find(needle)
    if start < 0:
        print("not found")
        continue
    lo = max(0, start - 1200)
    hi = min(len(text), start + 1800)
    print(text[lo:hi])
PY

printf '%s\n' '--- concise matching implementation references ---'
rg -o -n '.{0,180}npmPreapprovedPackages.{0,260}|.{0,180}function h0t.{0,700}|.{0,180}function g0t.{0,300}' .yarn/releases/yarn-4.13.0.cjs

Repository: SpecterOps/BloodHound

Length of output: 10650


🌐 Web query:

site:yarnpkg.com/configuration/yarnrc npmPreapprovedPackages "npm:"

💡 Result:

The npmPreapprovedPackages setting is a configuration option specifically for Yarn, not for the npm CLI [1]. It is defined in the.yarnrc.yml configuration file [1]. This setting allows you to specify an array of package descriptors or glob patterns for package names that should be excluded from all package gates [1]. When a package matches one of these patterns, it is exempted from evaluation by any active package gates, meaning it will not be restricted or checked by them [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
from pathlib import Path
text = Path(".yarn/releases/yarn-4.13.0.cjs").read_text()

needles = ["tryParseDescriptor", "parseDescriptor", "validRange"]
for needle in needles:
    positions = []
    start = 0
    while True:
        pos = text.find(needle, start)
        if pos < 0:
            break
        positions.append(pos)
        start = pos + 1
    print(f"{needle}: {len(positions)} occurrences")
    for pos in positions[:8]:
        print(text[max(0, pos-180):pos+420])
        print("---")
PY

Repository: SpecterOps/BloodHound

Length of output: 13562


🏁 Script executed:

#!/bin/bash
set -eu

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

text = Path(".yarn/releases/yarn-4.13.0.cjs").read_text()

for pattern in [r'function T2\([^)]*\)\{', r'function E0\([^)]*\)\{', r'function Mn\([^)]*\)\{']:
    m = re.search(pattern, text)
    print(f"--- {pattern} ---")
    if not m:
        print("not found")
        continue
    print(text[m.start():m.start()+1800])
PY

Repository: SpecterOps/BloodHound

Length of output: 5655


🏁 Script executed:

#!/bin/bash
set -eu

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

text = Path(".yarn/releases/yarn-4.13.0.cjs").read_text()

for pattern in [
    r'var NZe=',
    r'var FZe=',
    r'function dl\([^)]*\)\{',
]:
    print(f"--- {pattern} ---")
    m = re.search(pattern, text)
    if not m:
        print("not found")
        continue
    print(text[m.start():m.start()+1400])
PY

Repository: SpecterOps/BloodHound

Length of output: 1645


🏁 Script executed:

#!/bin/bash
set -eu

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

yarn = Path(".yarn/releases/yarn-4.13.0.cjs").read_text()
config = Path(".yarnrc.yml").read_text()
package = Path("package.json").read_text()

# These checks model the relevant bundled Yarn 4.13.0 logic:
# - bare descriptors have range "unknown" and match every version
# - validRange rejects ranges containing ":"
# - exact semver ranges match only the same version
def descriptor(entry):
    if "@" not in entry or entry.startswith("@") and entry.count("@") == 1:
        return entry, "unknown"
    name, version = entry.rsplit("@", 1)
    return name, version

def matches(entry, name, version):
    ident, range_ = descriptor(entry)
    if ident != name:
        return False
    if range_ == "unknown":
        return True
    if ":" in range_:
        return False
    return range_ == version

entries = re.findall(r"^\s*-\s+(.+?)\s*$", config, re.M)
entries = [e.strip('"\'') for e in entries if e in ("brace-expansion", "fast-uri") or "brace-expansion@" in e or "fast-uri@" in e]

versions = {
    "brace-expansion": re.search(r'"brace-expansion":\s*"([^"]+)"', package).group(1),
    "fast-uri": re.search(r'"fast-uri":\s*"([^"]+)"', package).group(1),
}
candidates = [
    "brace-expansion",
    "fast-uri",
    "brace-expansion@npm:5.0.9",
    "fast-uri@npm:3.1.5",
    "brace-expansion@5.0.9",
    "fast-uri@3.1.5",
]

for entry in candidates:
    name = entry.split("@", 1)[0]
    if name.startswith(""):
        target = versions.get(name)
    else:
        target = None
    print(f"{entry!r}: current-version-match={matches(entry, name, target) if target else False}")

assert matches("brace-expansion", "brace-expansion", "5.0.9")
assert matches("brace-expansion", "brace-expansion", "99.0.0")
assert matches("fast-uri", "fast-uri", "3.1.5")
assert matches("fast-uri", "fast-uri", "99.0.0")
assert not matches("brace-expansion@npm:5.0.9", "brace-expansion", "5.0.9")
assert not matches("fast-uri@npm:3.1.5", "fast-uri", "3.1.5")
assert matches("brace-expansion@5.0.9", "brace-expansion", "5.0.9")
assert matches("fast-uri@3.1.5", "fast-uri", "3.1.5")
assert not matches("brace-expansion@5.0.9", "brace-expansion", "5.0.10")
assert not matches("fast-uri@3.1.5", "fast-uri", "3.1.6")
print("all assertions passed")
PY

Repository: SpecterOps/BloodHound

Length of output: 470


🏁 Script executed:

#!/bin/bash
set -eu

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

yarn = Path(".yarn/releases/yarn-4.13.0.cjs").read_text()
config = Path(".yarnrc.yml").read_text()
package = Path("package.json").read_text()

def descriptor(entry):
    if "@" not in entry:
        return entry, "unknown"
    return entry.rsplit("@", 1)

def matches(entry, name, version):
    ident, range_ = descriptor(entry)
    if ident != name:
        return False
    if range_ == "unknown":
        return True
    if ":" in range_:
        return False
    return range_ == version

versions = {
    "brace-expansion": re.search(r'"brace-expansion":\s*"([^"]+)"', package).group(1),
    "fast-uri": re.search(r'"fast-uri":\s*"([^"]+)"', package).group(1),
}

for entry in [
    "brace-expansion",
    "fast-uri",
    "brace-expansion@npm:5.0.9",
    "fast-uri@npm:3.1.5",
    "brace-expansion@5.0.9",
    "fast-uri@3.1.5",
]:
    name = entry.split("@", 1)[0]
    print(f"{entry!r}: {matches(entry, name, versions[name])}")

assert matches("brace-expansion", "brace-expansion", "99.0.0")
assert matches("fast-uri", "fast-uri", "99.0.0")
assert not matches("brace-expansion@npm:5.0.9", "brace-expansion", "5.0.9")
assert not matches("fast-uri@npm:3.1.5", "fast-uri", "3.1.5")
assert matches("brace-expansion@5.0.9", "brace-expansion", "5.0.9")
assert matches("fast-uri@3.1.5", "fast-uri", "3.1.5")
print("all assertions passed")
PY

Repository: SpecterOps/BloodHound

Length of output: 338


Limit preapproval to the patched versions.

Bare package names match every version. Use exact descriptors without the npm: protocol:

 npmPreapprovedPackages:
-  - brace-expansion
-  - fast-uri
+  - "brace-expansion@5.0.9"
+  - "fast-uri@3.1.5"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
npmPreapprovedPackages:
- brace-expansion
- fast-uri
npmPreapprovedPackages:
- "brace-expansion@5.0.9"
- "fast-uri@3.1.5"
🤖 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 @.yarnrc.yml around lines 29 - 31, Update the npmPreapprovedPackages entries
for brace-expansion and fast-uri to exact package-version descriptors, without
the npm: protocol, so preapproval applies only to the patched versions.

@TheNando
TheNando merged commit 3f6345d into main Aug 3, 2026
14 of 15 checks passed
@TheNando
TheNando deleted the BED-9133-vulns branch August 3, 2026 21:48
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants