fix(deps): bump brace-expansion to patched versions for CVE-2026-13149 - #10
Merged
Conversation
brace-expansion was resolving to 1.1.15 (via minimatch@3) and 2.1.1 (via minimatch@9), both flagged by CVE-2026-13149 / GHSA-3jxr-9vmj-r5cp (DoS via exponential-time expansion of consecutive non-expanding {} groups), fixed in 1.1.16, 2.1.2 and 5.0.7 respectively. All existing transitive ranges (^1.1.7, ^2.0.2, ^5.0.5) already admit a patched release, so this is a lockfile-only re-resolve -- no overrides or resolutions pin needed in package.json. ^1.1.7 1.1.15 -> 1.1.17 ^2.0.2 2.1.1 -> 2.1.3 ^5.0.5 5.0.7 -> 5.0.8 Verified: CVE-2026-13149 no longer reported by npm audit; yarn install --frozen-lockfile and expo-module build both pass. Note: the unrelated CVE-2026-14257 / GHSA-mh99-v99m-4gvg (vulnerable range <=5.0.7, first patched only in 5.0.8) still flags the 1.x and 2.x lines, which have no patched release for it. Clearing that one needs a forced override across four majors of minimatch and is tracked separately. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ashirman
approved these changes
Jul 29, 2026
Adds .github/workflows/CI.yaml with two jobs, `check` (npm ci + npm run build) and `lint` (npm ci + npm run lint), running on PRs targeting main. Mirrors the code-push-server/cli workflow: SHA-pinned actions, least-privilege `contents: read`, and concurrency cancellation. Node is pinned to 20.19.4 rather than 20.19.0: the strictest engines constraint in the tree is react-native's `^20.19.4 || ^22.13.0 || ^24.3.0 || >=25.0.0`, which 20.19.0 does not satisfy. Repairing lint, which was broken before this change: - Add eslint.config.js (flat config). expo-module-scripts now ships ESLint 9, which ignores the legacy .eslintrc.js and failed with "couldn't find an eslint.config.(js|mjs|cjs) file". .eslintrc.js is kept because it is a non-optional expo-module-scripts template and is recreated by `expo-module prepare` on every install; ESLint 9 ignores it once a flat config is present. eslint.config.js is an optional template, so prepare keeps it in sync rather than clobbering it. - Declare eslint and prettier as devDependencies. Both are peers of eslint-config-universe with the open-ended ranges `>=8.10` and `>=3`. npm 7+ auto-installs peers (resolving eslint 9.39.4), but yarn 1 does not, so under yarn nothing provided eslint and `npx eslint` silently downloaded 10.8.0 -- which does not expose `eslint/config` and crashed the flat config. Pinning them makes npm and yarn agree and keeps CI from drifting onto a future ESLint major. Verified on Node 20.19.4: `npm ci`, `npm run build` and `npm run lint` all exit 0, as does `yarn lint`. Lint currently reports 192 prettier/prettier warnings (0 errors) in src/withRevopush.ts; these do not fail the build and are left for a separate formatting-only change to avoid conflicting with the in-flight feature branches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous layout ran `check` and `lint` as two jobs. Jobs do not share
a filesystem -- each gets its own runner -- so the split meant checking
out the repo twice and running `npm ci` twice. The install dominates
runtime here (~40s versus a few seconds for build and lint combined), so
the second job roughly doubled CI minutes to run one extra command.
Collapsed into one `check` job with Build and Lint as sequential steps.
Lint is guarded with `if: ${{ !cancelled() }}` so a build failure still
reports the lint result instead of hiding it behind another push.
Also:
- Add a `push: [main]` trigger, so a broken main is visible even when a
PR merges cleanly but the merge result does not build.
- Key `concurrency` on the PR number when present, falling back to
github.ref, so pushes to main are never cancelled by PR activity.
- Record why Node is pinned to 20.19.4 next to the pin itself.
main's branch protection currently has required_status_checks empty with
enforcement off, so dropping the separate "lint" context strands nothing.
The job keeps the name "check" to match org-wide protection.
Verified with actionlint (clean).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kit2o
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves CVE-2026-13149 / GHSA-3jxr-9vmj-r5cp — brace-expansion: DoS via exponential-time expansion of consecutive non-expanding
{}groups.brace-expansionwas resolving to 1.1.15 (transitively viaminimatch@3) and 2.1.1 (viaminimatch@9), both within the vulnerable ranges.Approach — lockfile only
Every existing transitive range already admits a patched release, so this is a pure lockfile re-resolve (
npm update brace-expansion --package-lock-only, which keepsyarn.lockin sync). Nooverrides/resolutionspin was needed inpackage.json— unlike the previous uuid fix (#9), nothing here required forcing a version outside its declared range.^1.1.7minimatch@3^2.0.2minimatch@9^5.0.5minimatch@10Patched versions per the advisory: 1.1.16, 2.1.2, 5.0.7.
Only
package-lock.jsonandyarn.lockchange.Verification
npm auditno longer reports GHSA-3jxr-9vmj-r5cp.yarn install --frozen-lockfilesucceeds; installed tree confirmed at 1.1.17 / 2.1.3 / 5.0.8.yarn build(expo-module build) passes.Out of scope — still open
<=5.0.7and it is first patched only in 5.0.8, so the 1.x and 2.x lines have no patched release at all. Clearing it would mean force-overriding every consumer to 5.0.8, crossing four majors forminimatch@3/@9— worth validating on its own rather than folding in here.<=8.5.17(GHSA-r28c-9q8g-f849) — unrelated; a non-breaking lockfile bump to 8.5.25 is available.🤖 Generated with Claude Code