CVE-2026-118773: Asynchronous Control Flow Bypass and Uncontrolled Resource Consumption in node-glob
Vulnerability ID: CVE-2026-118773
CVSS Score: 6.3
Published: 2026-10-30
CVE-2026-118773 (GHSA-3g3m-2fjr-6pw4) is an uncontrolled resource consumption vulnerability in the node-glob npm package affecting versions 9.0.0 through 14.0.1. Due to missing return statements in the AbortSignal check routines within the directory traversal walker, aborted operations reject the caller promise as expected but continue executing background filesystem reads and pattern matching. Applications that rely on AbortSignal or AbortSignal.timeout() to enforce execution budgets on user-influenced glob operations remain susceptible to CPU, event loop, and disk I/O exhaustion.
TL;DR
Missing return statements in node-glob's AbortSignal handling logic cause directory traversal operations to continue running in the background even after an operation is aborted or times out. Upgrading to glob version 14.0.2 resolves the issue by properly terminating the control flow upon signal abortion.
⚠️ Exploit Status: POC
Technical Details
- Vulnerability ID: CVE-2026-118773 / GHSA-3g3m-2fjr-6pw4
- Weakness Class: CWE-400 (Uncontrolled Resource Consumption)
- Affected Component: glob (node-glob) >= 9.0.0, < 14.0.2
- CVSS v4.0 Score: 6.3 Medium (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N)
- EPSS Score: 0.35% (28.69th Percentile)
- Impact: Post-timeout background filesystem traversal leading to I/O and CPU exhaustion
- Exploit Status: Proof-of-Concept (Unit test reproduction in patch commit)
- CISA KEV Status: Not Listed
Affected Systems
- node-glob (npm package: glob)
-
glob: >= 9.0.0, < 14.0.2 (Fixed in:
14.0.2)
Code Analysis
Commit: 4682e8c
fix: do not continue walking after signal abort
diff --git a/src/walker.ts b/src/walker.ts
index a675fee2..34f07665 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -155,7 +155,6 @@ export abstract class GlobUtil<O extends GlobWalkerOpts = GlobWalkerOpts> {
}
}
onResume(fn: () => unknown) {
- if (this.signal?.aborted) return
/* c8 ignore start */
if (!this.paused) {
fn()
@@ -281,7 +280,7 @@ export abstract class GlobUtil<O extends GlobWalkerOpts = GlobWalkerOpts> {
walkCB(target: Path, patterns: Pattern[], cb: () => unknown) {
/* c8 ignore start */
- if (this.signal?.aborted) cb()
+ if (this.signal?.aborted) return cb()
/* c8 ignore stop */
this.walkCB2(target, patterns, new Processor(this.opts), cb)
}
@@ -293,7 +292,7 @@ export abstract class GlobUtil<O extends GlobWalkerOpts = GlobWalkerOpts> {
cb: () => unknown,
) {
if (this.#childrenIgnored(target)) return cb()
- if (this.signal?.aborted) cb()
+ if (this.signal?.aborted) return cb()
if (this.paused) {
this.onResume(() => this.walkCB2(target, patterns, processor, cb))
return
@@ -365,7 +364,7 @@ export abstract class GlobUtil<O extends GlobWalkerOpts = GlobWalkerOpts> {
walkCBSync(target: Path, patterns: Pattern[], cb: () => unknown) {
/* c8 ignore start */
- if (this.signal?.aborted) cb()
+ if (this.signal?.aborted) return cb()
/* c8 ignore stop */
this.walkCB2Sync(target, patterns, new Processor(this.opts), cb)
}
@@ -377,7 +376,7 @@ export abstract class GlobUtil<O extends GlobWalkerOpts = GlobWalkerOpts> {
cb: () => unknown,
) {
if (this.#childrenIgnored(target)) return cb()
- if (this.signal?.aborted) cb()
+ if (this.signal?.aborted) return cb()
if (this.paused) {
this.onResume(() =>
this.walkCB2Sync(target, patterns, processor, cb),
Exploit Details
- GitHub: Official regression test case in test/signal.ts demonstrating continued fs.readdir and fs.readdirSync calls after AbortController.abort() is triggered.
Mitigation Strategies
- Upgrade node-glob to version 14.0.2 or later to ensure AbortSignal immediately terminates directory traversal routines.
- Validate and sanitize untrusted glob patterns by rejecting unbounded globstar (**) expressions and constraining traversal depth via the maxDepth option.
- Scope filesystem searches to narrow working directories (cwd) and configure explicit ignore patterns for large directory trees such as node_modules.
- Isolate potentially expensive glob operations inside dedicated worker threads or child processes that can be forcibly terminated via worker.terminate() or SIGKILL on timeout.
Remediation Steps:
- Audit project dependency trees using 'npm ls glob' or 'pnpm why glob' to identify direct and transitive installations of glob >= 9.0.0 and < 14.0.2.
- Update package.json manifests to require glob@^14.0.2 or apply package manager overrides/resolutions for transitive dependencies.
- Run regression tests to verify compatibility with glob v14.0.2 and confirm that aborted operations no longer generate background disk I/O.
References
- GitHub Security Advisory GHSA-3g3m-2fjr-6pw4
- Fix Commit: do not continue walking after signal abort
- node-glob Release v14.0.2
- NVD Vulnerability Detail: CVE-2026-118773
- CVE.org Record: CVE-2026-118773
Read the full report for CVE-2026-118773 on our website for more details including interactive diagrams and full exploit analysis.
Top comments (0)