
Cloud Vulnerability DB
A community-led vulnerabilities database
glob sets braceExpandMax: 10_000 when it parses pattern patterns, but
the Ignore class builds its own minimatch options and omits
braceExpandMax entirely, so ignore patterns fall back to minimatch's default
of 100_000. Both paths force optimizationLevel: 2, which is the exact
precondition for minimatch's globparts amplification (CVE-2026-118764,
GHSA-g3hv-75wg-m249) — minimatch's own default is 1.
The consequence is that the same payload is rejected in milliseconds when
passed as a pattern, but is accepted and burns far more CPU when passed as an
ignore pattern.
src/glob.ts:527-529 — pattern path, limit present:
const mmo: MinimatchOptions = {
braceExpandMax: 10_000,
...opts,src/ignore.ts:71-83 — ignore path, limit missing:
this.mmopts = {
dot: true,
nobrace,
nocase,
noext,
noglobstar,
normalize,
optimizationLevel: 2, // forced, and the amplification precondition
platform,
nocomment: true,
nonegate: true,
windowsPathsNoEscape,
} // <-- no braceExpandMaxminimatch >= 11.0.1 fixed CVE-2026-118764 by throwing a RangeError once
globParts.length >= braceExpandMax. The pattern path caps rows at 10_000;
the ignore path allows 100_000. The amplified rows then go through
minimatch's secondPhasePreProcess(), which is O(n²) pairwise partsMatch.
import { Volume, createFsFromVolume } from 'memfs'
import { glob } from 'glob'
const vol = new Volume()
const fs = createFsFromVolume(vol)
vol.fromJSON({ '/p/f.txt': 'x' })
// 14 '**/..' groups -> 2^14 = 16384 rows, over the 10_000 limit
const payload = Array.from({ length: 14 })
.map((_, i) => `**/../x${i}/y${i}`)
.join('/')
glob.sync(payload, { cwd: '/p', fs, platform: 'posix' })
// throws: optimizationLevel 2: too many patterns from '**/..' (rejected fast)
glob.sync('*', { cwd: '/p', fs, ignore: [payload], platform: 'posix' })
// accepted, ~1.5-2.0 s of CPUMeasured on the published glob@14.0.4:
payload: 175 bytes
as PATTERN : 6 ms REJECTED (optimizationLevel 2: too many patterns from '**/..)
as IGNORE : 1985 ms acceptedAn attacker who can influence ignore patterns can force disproportionate CPU consumption on the event loop.
Issue is in src/ignore.ts. A minimal change closes them:
this.mmopts = {
+ braceExpandMax: 10_000,
dot: true,
nobrace,
nocase,
@@
this.slashRoot = escape(
slashRoot.replace(/\\/g, '/').replace(/\/$/, ''),
- { windowsPathsNoEscape },
+ { magicalBraces: true, windowsPathsNoEscape },
)magicalBraces: true makes escape() escape { and } as well, so the
composed path stays literal and is not brace-expanded on re-parse.braceExpandMax: 10_000 makes the ignore path use the same limit as the
pattern path.
Verified: with this patch the ignore matcher becomes[['', 'root{7,8}', 'skip.log']] (one row, literal), matches
/root{7,8}/skip.log, and the amplified ignore payload is rejected with the
same error as the pattern path.
Regression tests are in test/ignore-braces.ts; they fail against the
unpatched source and pass with the patch. The existing suite
(test/ignore.ts, test/custom-ignore.ts, test/ignore-root.ts,
test/pattern.ts, test/root.ts, test/absolute.ts) remains green: 167/167.
Tested on published glob@14.0.4 (current HEAD f26bdac). Earlier versions not checked. Fixed in: not yet released.
Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."