Skip to content

Fix Security baseline gate: override brace-expansion in eslint's dependency tree#473

Open
richard-devbot wants to merge 1 commit into
mainfrom
fix-eslint-security-advisory
Open

Fix Security baseline gate: override brace-expansion in eslint's dependency tree#473
richard-devbot wants to merge 1 commit into
mainfrom
fix-eslint-security-advisory

Conversation

@richard-devbot

Copy link
Copy Markdown
Owner

Summary

  • Fixes Security baseline gate failing: eslint's transitive brace-expansion advisory #472 — CI's Security baseline job fails on main right now, independent of any PR. npm audit reports 5 high-severity advisories, all tracing to one root: a DoS/ReDoS bug in brace-expansion (GHSA-3jxr-9vmj-r5cp, GHSA-mh99-v99m-4gvg), reachable via eslint -> minimatch@3.1.5 -> brace-expansion@1.1.16.
  • npm audit's only reported fix was eslint@10 (isSemVerMajor: true) — tried it, but @eslint/js's ESLint-10 recommended config adds a new no-useless-assignment rule that flags 15 pre-existing dead-store patterns across src/. Too invasive for what's really a transitive-dependency-only issue (eslint is a devDependency, never installed by npm install rstack-agents).
  • Instead: added a root overrides entry (same mechanism this repo already uses for esbuild/protobufjs/ws) forcing brace-expansion to the patched 5.0.8 line. Confirmed this reaches eslint's own tree while — as the script's own comments document — leaving @earendil-works/pi-coding-agent's shrinkwrapped copy (5.0.6) untouched (npm honors a shrinkwrap absolutely; overrides can't reach it).
  • That shrinkwrapped copy is the only remaining high-severity finding, and it's exactly the node security-audit.mjs's BUNDLED_ROOTS/TOLERATED_BUNDLED_ADVISORIES allowlist already exists to tolerate. Added the second GHSA id to that allowlist — the gate is deliberately strict per-advisory-id (a newly-surfaced GHSA for an already-tolerated package still fails until consciously added), so this is a real, intentional decision, not a silent widening.

Test plan

  • npm run lint — unchanged (0 errors, same 4 pre-existing warnings), confirming minimatch@3.1.5 works fine against the newer brace-expansion at runtime
  • npm run typecheck — 0 errors
  • npm audit --json — only the already-tolerated bundled pi-coding-agent node remains; simulated the gate's own logic against the real audit output and confirmed 0 blocking
  • Full local test suite: same pre-existing failure count (locally, this Windows sandbox can't resolve bare npx/npm in spawn() without a shell — a known, unrelated environment limitation that also affects an unmodified main checkout identically; CI runs on Linux where this doesn't apply, same as the last two PRs)

…#472)

npm audit reported 5 high-severity advisories, all tracing to one root:
a DoS/ReDoS bug in brace-expansion (GHSA-3jxr-9vmj-r5cp,
GHSA-mh99-v99m-4gvg), reachable via eslint -> minimatch@3.1.5 ->
brace-expansion@1.1.16. npm's only reported fix was eslint@10
(isSemVerMajor), which pulls in a new no-useless-assignment rule
in @eslint/js's recommended config, flagging 15 pre-existing
dead-store patterns across src/ -- too invasive for a security-only
fix.

Instead: add a root `overrides` entry (this repo already uses the
same mechanism for esbuild/protobufjs/ws) forcing brace-expansion to
the patched 5.0.8 line. Verified this reaches eslint's own tree
(minimatch@3.1.5's brace-expansion now 5.0.8) while, as documented,
leaving @earendil-works/pi-coding-agent's shrinkwrapped copy (5.0.6)
untouched -- npm honors a shrinkwrap absolutely, so overrides can't
reach it regardless.

That shrinkwrapped copy is the only remaining high-severity finding,
and it's exactly the node this gate's BUNDLED_ROOTS/
TOLERATED_BUNDLED_ADVISORIES allowlist already exists to tolerate --
added the second GHSA id to that allowlist (the gate is deliberately
strict per-advisory-id, so a newly surfaced GHSA for an
already-tolerated package still fails until consciously added).

Verified: npm run lint unchanged (0 errors, same 4 pre-existing
warnings -- confirms minimatch@3.1.5 works fine with the newer
brace-expansion at runtime), npm run typecheck clean, gate logic
simulated against real npm audit output now reports 0 blocking.
@strix-security

strix-security Bot commented Jul 26, 2026

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for 780ed06.


Reviewed by Strix
Re-run review · Configure security review settings

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@richard-devbot, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 18 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f9a7f9e0-dc58-4c24-9bdb-d729902d5f96

📥 Commits

Reviewing files that changed from the base of the PR and between cce8808 and 780ed06.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • package.json
  • scripts/security-audit.mjs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-eslint-security-advisory

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix CI security baseline by overriding brace-expansion in ESLint tree

🐞 Bug fix ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Force patched brace-expansion version via npm overrides to unblock Security baseline gate.
• Update lockfile so ESLint’s minimatch chain resolves brace-expansion@5.0.8.
• Extend audit allowlist for shrinkwrapped bundled dependency to include newly surfaced GHSA.
Diagram

graph TD
  CI(["CI: Security baseline"]) --> AUD(["npm audit"]) --> GATE["scripts/security-audit.mjs"] --> OVR["package.json overrides"] --> LOCK["package-lock.json"]
  LOCK --> ESL["eslint → minimatch → brace-expansion@5.0.8"] --> OK["Gate passes"]
  LOCK --> BND["pi-coding-agent bundled brace-expansion@5.0.6"] --> ALW["Tolerated GHSA ids"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Upgrade ESLint major (eslint@10) and fix new lint violations
  • ➕ Eliminates the vulnerable transitive dependency without overrides
  • ➕ Aligns with upstream latest rules and ecosystem
  • ➖ Introduces new recommended rules causing non-trivial code churn (existing dead stores)
  • ➖ Higher risk/scope for what is effectively a devDependency-only audit issue
2. Update/replace the shrinkwrapped bundled dependency (pi-coding-agent)
  • ➕ Removes the last remaining high-severity advisory without allowlisting
  • ➕ Avoids relying on per-GHSA toleration over time
  • ➖ May require upstream release coordination or vendor changes
  • ➖ Potentially larger dependency and integration impact than a targeted override
3. Switch package manager/resolution mechanism (e.g., pnpm overrides/yarn resolutions)
  • ➕ Can offer more control/visibility over transitive dependency policies
  • ➕ May simplify future security remediation workflows
  • ➖ Tooling migration cost; impacts dev workflow and CI
  • ➖ Not necessary to address the immediate gate failure

Recommendation: The chosen approach (root-level npm overrides + explicit per-GHSA allowlisting for the unavoidable shrinkwrapped node) is the best short-term fix: it remediates the vulnerable ESLint dependency chain without a disruptive major ESLint upgrade, and keeps the security gate intentionally strict by requiring an explicit decision for each GHSA id. A follow-up should target the remaining shrinkwrapped brace-expansion by updating the bundled dependency upstream to eliminate the need for toleration.

Files changed (3) +24 / -27

Bug fix (1) +7 / -3
security-audit.mjsAllowlist additional brace-expansion GHSA for bundled shrinkwrap node +7/-3

Allowlist additional brace-expansion GHSA for bundled shrinkwrap node

• Extends the per-advisory-id allowlist for the bundled/shrinkwrapped brace-expansion instance to include GHSA-mh99-v99m-4gvg alongside the already tolerated GHSA-3jxr-9vmj-r5cp. Updates comments to document why the remaining finding is confined to the bundled root and why overrides cannot affect it.

scripts/security-audit.mjs

Other (2) +17 / -24
package-lock.jsonResolve brace-expansion to 5.0.8 and refresh dependent nodes +15/-23

Resolve brace-expansion to 5.0.8 and refresh dependent nodes

• Updates the lockfile so the eslint→minimatch chain no longer pulls brace-expansion@1.1.16, instead resolving brace-expansion@5.0.8. This also updates brace-expansion’s direct dependency (balanced-match) and removes concat-map from the resolved tree, reflecting the newer major line.

package-lock.json

package.jsonAdd npm override to pin brace-expansion to patched range +2/-1

Add npm override to pin brace-expansion to patched range

• Adds a top-level npm overrides rule forcing brace-expansion to >=5.0.8, consistent with existing overrides usage in the repo. This targets the transitive dependency causing the Security baseline gate failure without upgrading ESLint major.

package.json

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 300 rules
✅ Skills: 17 invoked
  code-review-pr
  claude-api
  documentation-writing
  pptx
  docx
  performance-monitoring
  security-compliance
  cso
  plan-eng-review
  design-review
  prompt-engineering
  mcp-builder
  qa-testing
  code-patterns
  xlsx
  security-owasp
  testing-qa

Grey Divider


Remediation recommended

1. Node version mismatch 🐞 Bug ☼ Reliability
Description
The override pulls in brace-expansion@5.0.8 which declares Node "20 || >=22", but this repo declares
Node ">=18" and CI still runs a Node 18.x lane. This can cause install-time engine failures (in
stricter environments) or make the Node 18 lane brittle when the overridden dependency is exercised
(e.g., lint tooling).
Code

package-lock.json[R3569-3580]

    "node_modules/brace-expansion": {
-      "version": "1.1.16",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
-      "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
+      "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
+        "balanced-match": "^4.0.2"
+      },
+      "engines": {
+        "node": "20 || >=22"
      }
Relevance

⭐⭐⭐ High

They’ve accepted Node version consistency fixes; engine mismatch could break Node 18 CI/install.

PR-#171

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The repo declares/support-tests Node 18, but the updated lockfile shows the overridden
brace-expansion now requires Node 20+.

package.json[41-43]
.github/workflows/ci.yml[13-17]
package-lock.json[3569-3580]
package.json[114-119]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`brace-expansion@5.0.8` is now forced into the root dependency tree, but it declares `engines.node = "20 || >=22"`, conflicting with this repo’s declared `engines.node >=18` and the CI matrix that still runs Node 18.

## Issue Context
Even if npm only warns by default, this becomes a hard failure in environments that enforce engines (or if the dependency starts using Node 20-only APIs).

## Fix Focus Areas
- package.json[41-43]
- package.json[114-119]
- .github/workflows/ci.yml[13-17]
- package-lock.json[3569-3580]

## What to change
Choose one:
1) If Node 18 is truly supported: use a patched `brace-expansion` version that supports Node 18, or scope the override so Node 18 paths don’t require Node 20-only packages.
2) If Node 18 is *not* supported in practice: update `package.json` engines and remove Node 18 from the CI matrix so the declared support matches reality.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. security-audit.mjs change lacks tests 📘 Rule violation ▣ Testability
Description
This PR changes the Security baseline gate behavior by expanding TOLERATED_BUNDLED_ADVISORIES to
accept an additional GHSA ID, but no automated tests were added/updated in the same changeset to
cover this new allowlist behavior. Without tests, future refactors may unintentionally
broaden/narrow the gate logic and break CI or weaken security controls silently.
Code

scripts/security-audit.mjs[R31-42]

+// - brace-expansion GHSA-3jxr-9vmj-r5cp + GHSA-mh99-v99m-4gvg (both DoS):
+//   pinned 5.0.6 by pi's shrinkwrap, both advisories confined to that one
+//   bundled node (verified: eslint's own brace-expansion moved to the
+//   patched 5.0.8 after #472's eslint 9->10 bump, so only the shrinkwrapped
+//   copy remains on the vulnerable <=5.0.7 line); every non-shrinkwrapped
+//   path in our tree is on the fixed line.
// - protobufjs / ws: previously tolerated by name while their advisories were
//   live in the bundled subtree; currently dormant, so no ids are listed — if
//   one refires, the gate fails loudly and the specific GHSA gets re-added.
const TOLERATED_BUNDLED_ADVISORIES = new Map([
-  ['brace-expansion', new Set(['GHSA-3jxr-9vmj-r5cp'])],
+  ['brace-expansion', new Set(['GHSA-3jxr-9vmj-r5cp', 'GHSA-mh99-v99m-4gvg'])],
]);
Relevance

⭐⭐ Medium

They recently changed security-audit allowlist logic, but no evidence they require tests for
allowlist updates.

PR-#439

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1587034 requires that non-trivial behavior changes include accompanying automated
tests in the same changeset. The diff shows the gate behavior was changed by adding
GHSA-mh99-v99m-4gvg to the tolerated advisory IDs in scripts/security-audit.mjs, but no test
changes are present in the PR diff.

Rule 1587034: Require tests in the same changeset as behavior modifications
scripts/security-audit.mjs[31-42]
.github/workflows/ci.yml[97-101]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR updates `scripts/security-audit.mjs` to tolerate an additional `brace-expansion` advisory ID, which changes CI gate behavior, but there is no corresponding test change in this PR to lock in the intended behavior.

## Issue Context
The `security-baseline` CI job runs `node scripts/security-audit.mjs`, so changes to this script are executable behavior changes and should be covered by automated tests.

## Fix Focus Areas
- scripts/security-audit.mjs[31-42]
- tests/security-audit.test.js[1-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Unbounded override range 🐞 Bug ⚙ Maintainability
Description
The override uses ">=5.0.8", which allows future lockfile regenerations to select newer (including
potentially breaking) major versions of brace-expansion. It also forces minimatch@3.1.5 to run
against brace-expansion 5.x even though minimatch declares a 1.x range, creating an ongoing
transitive-compatibility risk.
Code

package.json[R114-118]

  "overrides": {
    "esbuild": ">=0.28.1",
    "protobufjs": ">=7.6.4 <8",
-    "ws": ">=8.21.0"
+    "ws": ">=8.21.0",
+    "brace-expansion": ">=5.0.8"
Relevance

⭐⭐ Medium

No precedent on pinning overrides; repo already uses unbounded ">=" overrides, so change is
subjective.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new override is unbounded and the lockfile shows minimatch depends on brace-expansion ^1.1.7,
demonstrating the override is crossing a major range boundary.

package.json[114-119]
package-lock.json[4994-5005]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The override `"brace-expansion": ">=5.0.8"` is open-ended and can float to future major releases when the lockfile is regenerated. It also overrides `minimatch@3.1.5`’s declared dependency range (`^1.1.7`), so the repo is relying on compatibility that npm is no longer enforcing.

## Issue Context
Right now the lockfile pins `brace-expansion` to `5.0.8`, but the manifest range increases the chance of unexpected breakage on routine dependency maintenance.

## Fix Focus Areas
- package.json[114-119]
- package-lock.json[4994-5005]

## What to change
- Prefer pinning to an exact version (`"5.0.8"`) or a bounded range (`"^5.0.8"`).
- Consider scoping the override to only the eslint/minimatch subtree (npm overrides support nested overrides) so you don’t globally replace every consumer’s `brace-expansion` with a potentially incompatible major.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

4. Incorrect audit script comment 🐞 Bug ⚙ Maintainability
Description
The updated comment claims eslint’s brace-expansion moved to 5.0.8 due to an “eslint 9->10 bump”,
but this PR keeps eslint at ^9 and makes the change via npm overrides. This mismatch can mislead
future debugging of the security baseline gate.
Code

scripts/security-audit.mjs[R31-36]

+// - brace-expansion GHSA-3jxr-9vmj-r5cp + GHSA-mh99-v99m-4gvg (both DoS):
+//   pinned 5.0.6 by pi's shrinkwrap, both advisories confined to that one
+//   bundled node (verified: eslint's own brace-expansion moved to the
+//   patched 5.0.8 after #472's eslint 9->10 bump, so only the shrinkwrapped
+//   copy remains on the vulnerable <=5.0.7 line); every non-shrinkwrapped
+//   path in our tree is on the fixed line.
Relevance

⭐⭐⭐ High

Misleading comment is a straightforward maintainability fix; likely to be accepted when pointed out.

PR-#439

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The comment explicitly references an ESLint bump, but package.json shows ESLint is still ^9.0.0 and
the PR change is an override entry.

scripts/security-audit.mjs[31-36]
package.json[101-106]
package.json[114-119]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The comment in `scripts/security-audit.mjs` attributes the brace-expansion change to an ESLint 9→10 bump, but the repo is still on ESLint `^9.0.0` and the actual mechanism is a root `overrides` entry.

## Issue Context
This is documentation-only, but it directly affects maintainers’ ability to reason about why the vulnerability is (or isn’t) present.

## Fix Focus Areas
- scripts/security-audit.mjs[31-36]
- package.json[101-106]
- package.json[114-119]

## What to change
Rewrite the comment to say the non-shrinkwrapped tree is fixed due to the root `overrides` forcing `brace-expansion@5.0.8`, while the shrinkwrapped `@earendil-works/pi-coding-agent` copy remains pinned and tolerated by advisory id.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +31 to 42
// - brace-expansion GHSA-3jxr-9vmj-r5cp + GHSA-mh99-v99m-4gvg (both DoS):
// pinned 5.0.6 by pi's shrinkwrap, both advisories confined to that one
// bundled node (verified: eslint's own brace-expansion moved to the
// patched 5.0.8 after #472's eslint 9->10 bump, so only the shrinkwrapped
// copy remains on the vulnerable <=5.0.7 line); every non-shrinkwrapped
// path in our tree is on the fixed line.
// - protobufjs / ws: previously tolerated by name while their advisories were
// live in the bundled subtree; currently dormant, so no ids are listed — if
// one refires, the gate fails loudly and the specific GHSA gets re-added.
const TOLERATED_BUNDLED_ADVISORIES = new Map([
['brace-expansion', new Set(['GHSA-3jxr-9vmj-r5cp'])],
['brace-expansion', new Set(['GHSA-3jxr-9vmj-r5cp', 'GHSA-mh99-v99m-4gvg'])],
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. security-audit.mjs change lacks tests 📘 Rule violation ▣ Testability

This PR changes the Security baseline gate behavior by expanding TOLERATED_BUNDLED_ADVISORIES to
accept an additional GHSA ID, but no automated tests were added/updated in the same changeset to
cover this new allowlist behavior. Without tests, future refactors may unintentionally
broaden/narrow the gate logic and break CI or weaken security controls silently.
Agent Prompt
## Issue description
The PR updates `scripts/security-audit.mjs` to tolerate an additional `brace-expansion` advisory ID, which changes CI gate behavior, but there is no corresponding test change in this PR to lock in the intended behavior.

## Issue Context
The `security-baseline` CI job runs `node scripts/security-audit.mjs`, so changes to this script are executable behavior changes and should be covered by automated tests.

## Fix Focus Areas
- scripts/security-audit.mjs[31-42]
- tests/security-audit.test.js[1-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread package-lock.json
Comment on lines 3569 to 3580
"node_modules/brace-expansion": {
"version": "1.1.16",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
"integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
"integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
"balanced-match": "^4.0.2"
},
"engines": {
"node": "20 || >=22"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Node version mismatch 🐞 Bug ☼ Reliability

The override pulls in brace-expansion@5.0.8 which declares Node "20 || >=22", but this repo declares
Node ">=18" and CI still runs a Node 18.x lane. This can cause install-time engine failures (in
stricter environments) or make the Node 18 lane brittle when the overridden dependency is exercised
(e.g., lint tooling).
Agent Prompt
## Issue description
`brace-expansion@5.0.8` is now forced into the root dependency tree, but it declares `engines.node = "20 || >=22"`, conflicting with this repo’s declared `engines.node >=18` and the CI matrix that still runs Node 18.

## Issue Context
Even if npm only warns by default, this becomes a hard failure in environments that enforce engines (or if the dependency starts using Node 20-only APIs).

## Fix Focus Areas
- package.json[41-43]
- package.json[114-119]
- .github/workflows/ci.yml[13-17]
- package-lock.json[3569-3580]

## What to change
Choose one:
1) If Node 18 is truly supported: use a patched `brace-expansion` version that supports Node 18, or scope the override so Node 18 paths don’t require Node 20-only packages.
2) If Node 18 is *not* supported in practice: update `package.json` engines and remove Node 18 from the CI matrix so the declared support matches reality.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread package.json
Comment on lines 114 to +118
"overrides": {
"esbuild": ">=0.28.1",
"protobufjs": ">=7.6.4 <8",
"ws": ">=8.21.0"
"ws": ">=8.21.0",
"brace-expansion": ">=5.0.8"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. Unbounded override range 🐞 Bug ⚙ Maintainability

The override uses ">=5.0.8", which allows future lockfile regenerations to select newer (including
potentially breaking) major versions of brace-expansion. It also forces minimatch@3.1.5 to run
against brace-expansion 5.x even though minimatch declares a 1.x range, creating an ongoing
transitive-compatibility risk.
Agent Prompt
## Issue description
The override `"brace-expansion": ">=5.0.8"` is open-ended and can float to future major releases when the lockfile is regenerated. It also overrides `minimatch@3.1.5`’s declared dependency range (`^1.1.7`), so the repo is relying on compatibility that npm is no longer enforcing.

## Issue Context
Right now the lockfile pins `brace-expansion` to `5.0.8`, but the manifest range increases the chance of unexpected breakage on routine dependency maintenance.

## Fix Focus Areas
- package.json[114-119]
- package-lock.json[4994-5005]

## What to change
- Prefer pinning to an exact version (`"5.0.8"`) or a bounded range (`"^5.0.8"`).
- Consider scoping the override to only the eslint/minimatch subtree (npm overrides support nested overrides) so you don’t globally replace every consumer’s `brace-expansion` with a potentially incompatible major.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +31 to +36
// - brace-expansion GHSA-3jxr-9vmj-r5cp + GHSA-mh99-v99m-4gvg (both DoS):
// pinned 5.0.6 by pi's shrinkwrap, both advisories confined to that one
// bundled node (verified: eslint's own brace-expansion moved to the
// patched 5.0.8 after #472's eslint 9->10 bump, so only the shrinkwrapped
// copy remains on the vulnerable <=5.0.7 line); every non-shrinkwrapped
// path in our tree is on the fixed line.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Informational

4. Incorrect audit script comment 🐞 Bug ⚙ Maintainability

The updated comment claims eslint’s brace-expansion moved to 5.0.8 due to an “eslint 9->10 bump”,
but this PR keeps eslint at ^9 and makes the change via npm overrides. This mismatch can mislead
future debugging of the security baseline gate.
Agent Prompt
## Issue description
The comment in `scripts/security-audit.mjs` attributes the brace-expansion change to an ESLint 9→10 bump, but the repo is still on ESLint `^9.0.0` and the actual mechanism is a root `overrides` entry.

## Issue Context
This is documentation-only, but it directly affects maintainers’ ability to reason about why the vulnerability is (or isn’t) present.

## Fix Focus Areas
- scripts/security-audit.mjs[31-36]
- package.json[101-106]
- package.json[114-119]

## What to change
Rewrite the comment to say the non-shrinkwrapped tree is fixed due to the root `overrides` forcing `brace-expansion@5.0.8`, while the shrinkwrapped `@earendil-works/pi-coding-agent` copy remains pinned and tolerated by advisory id.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

Security baseline gate failing: eslint's transitive brace-expansion advisory

2 participants