Skip to content

Commit 8144e75

Browse files
authored
Bump brace-expansion to fix GHSA-f886-m6hf-6m8v in /.github/actions/upload-artifact-s3 (#8038)
## Summary Patches the regex-DoS in `brace-expansion` ([GHSA-f886-m6hf-6m8v](GHSA-f886-m6hf-6m8v) / CVE-2026-33750) inside `.github/actions/upload-artifact-s3` by upgrading the transitive `brace-expansion` dependency: - `1.1.11` → `1.1.14` - `2.0.1` → `2.1.0` `brace-expansion` reaches this action's runtime through `@actions/glob` → `minimatch` → `brace-expansion` and is inlined into the action's bundled entrypoint by `@vercel/ncc`. ## Changes 1. **`package-lock.json`** — pins both transitive instances of `brace-expansion` to the patched releases. No `package.json` edits; nothing in this action's tree depends on `brace-expansion` directly. 2. **`dist/upload/index.js`** — regenerated with `npm run release` (`@vercel/ncc`). The bundled `brace-expansion` source now contains the upstream patches: - `expand()` accepts a `max` option and stops emitting expansions once that bound is reached. - The fast-path post-brace probe regex changes from `/,.*\}/` to `/,(?!,).*\}/`, eliminating quadratic backtracking on dense-comma inputs. - Numeric brace step is clamped via `Math.max(Math.abs(step), 1)`, so `{N..M..0}` no longer infinite-loops. 3. **`__tests__/brace-expansion.test.ts`** — two regression tests against `minimatch.braceExpand` covering the two patched code paths (zero-step `{1..3..0}` and dense-comma malformed input). The tests run against the brace-expansion 2.x copy that ships with the action's direct `minimatch` dep; the 1.x copy bundled into `dist/upload/index.js` carries the same upstream patches and is guarded against lockfile/dist drift by the existing `check-dist` CI job. Closes T261666678.
1 parent 157a448 commit 8144e75

3 files changed

Lines changed: 132 additions & 84 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {describe, expect, it} from '@jest/globals'
2+
import {braceExpand} from 'minimatch'
3+
4+
// Regression tests for GHSA-f886-m6hf-6m8v / CVE-2026-33750 in brace-expansion.
5+
//
6+
// minimatch is a direct runtime dep of this action and pulls in
7+
// brace-expansion 2.x. The vendored copy bundled into dist/upload/index.js
8+
// (via @actions/glob -> minimatch -> brace-expansion 1.x) carries the
9+
// same patches; check-dist guards lockfile/dist drift.
10+
//
11+
// Vulnerable versions: brace-expansion <=1.1.13 (1.x) and <=2.0.1 (2.x).
12+
// Patched versions: 1.1.14 / 2.1.0.
13+
//
14+
// On vulnerable versions both inputs below either hung indefinitely
15+
// (zero-step numeric range) or quadratically backtracked the post-brace
16+
// regex (dense-comma post). On patched versions both return promptly with
17+
// the asserted output.
18+
19+
const TIME_BUDGET_MS = 1000
20+
21+
describe('brace-expansion (GHSA-f886-m6hf-6m8v) regression', () => {
22+
it('zero-step numeric range expands to a finite, deterministic list', () => {
23+
// Vulnerable versions infinite-looped on `{N..M..0}` because the step
24+
// was used as-is. Patch clamps via Math.max(Math.abs(step), 1) so the
25+
// step degrades to 1 and the range expands deterministically.
26+
const start = Date.now()
27+
const out = braceExpand('{1..3..0}')
28+
expect(Date.now() - start).toBeLessThan(TIME_BUDGET_MS)
29+
expect(out).toEqual(['1', '2', '3'])
30+
})
31+
32+
it('dense-comma malformed input does not exhibit ReDoS', () => {
33+
// Vulnerable versions matched the post-brace tail against /,.*\}/,
34+
// which quadratically backtracks on a long run of commas with no
35+
// closing brace. Patch tightens the regex to /,(?!,).*\}/. With no
36+
// closing brace anywhere the input is malformed and brace-expansion
37+
// returns it unchanged; we assert that to lock in correctness as
38+
// well as termination.
39+
const dense = ','.repeat(10_000)
40+
const input = `{a}${dense}`
41+
const start = Date.now()
42+
const out = braceExpand(input)
43+
expect(Date.now() - start).toBeLessThan(TIME_BUDGET_MS)
44+
expect(out).toEqual([input])
45+
})
46+
})

.github/actions/upload-artifact-s3/dist/upload/index.js

Lines changed: 14 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)