{"id":"CVE-2026-118773","aliases":["GHSA-3g3m-2fjr-6pw4"],"title":"Glob: AbortSignal cancellation bypass allows post-timeout filesystem traversal","titleSource":"GitHub_M","descriptionSource":"OSV","declaredSeverity":"MODERATE","description":"### Summary\n\nIn glob 13.0.6, an aborted async walk rejects or emits an error but continues recursively reading directories in the background.\n\nThe root cause is that abort branches in src/walker.ts call cb() without returning. As a result, callers that rely on signal or AbortSignal.timeout() to bound glob traversal cost can still incur filesystem I/O and CPU work after the request has already been rejected.\n\n### Details\n\nThis was reproduced on glob v13.0.6 (commit e80cb38ae60d6cbff9e75f39032a994858994d35).\n\nThe README documents that the signal option cancels the glob walk. However, in src/walker.ts, the following methods call cb() when this.signal?.aborted is true but do not return:\n\n- GlobUtil.walkCB()\n- GlobUtil.walkCB2()\n- GlobUtil.walkCBSync()\n- GlobUtil.walkCB2Sync()\n\nExample vulnerable pattern:\n\nif (this.signal?.aborted) cb()\n\nBecause execution continues after cb(), the walker still reaches processor.processPatterns(), readdirCB(), and recursive walkCB2() calls.\n\nThe issue was directly demonstrated against v13.0.6. A source-history review shows the same missing-return pattern is present in tagged releases from v9.0.0 through v13.0.6.\n\nThe issue affects both glob() and globStream().\n\nRecommended fix:\nChange each abort branch to return immediately:\n\nif (this.signal?.aborted) return cb()\n\n### Proof of concept\n\nEnvironment:\n- Linux x86_64\n- Node.js v22.23.3\n- npm 10.9.9\n- glob 13.0.6\n\nReproduction steps:\n\n1. Install the affected package:\n   npm init -y\n   npm install glob@13.0.6\n\n2. Run the attached PoC:\n   node poc/abort-continues-work.mjs\n\nThe PoC aborts after the first readdir() call, waits briefly, and counts how many more directory reads happen after the promise has already rejected.\n\nObserved output on the vulnerable version:\n\n{\n  \"rejection\": \"Error: probe-abort\",\n  \"readdirCalls\": 1365,\n  \"readdirCallsAtReject\": 5,\n  \"readdirCallsAfterReject\": 1360\n}\n\nExpected behavior:\nreaddirCallsAfterReject should be 0.\n\nA second PoC using AbortSignal.timeout() also reproduces the issue:\n\n{\n  \"rejection\": \"TimeoutError: The operation was aborted due to timeout\",\n  \"readdirCalls\": 133,\n  \"readdirCallsAtReject\": 1,\n  \"readdirCallsAfterReject\": 132\n}\n\nThe same test against a patched build with return cb() in the four abort branches stops immediately:\n\n{\n  \"readdirCalls\": 1,\n  \"readdirCallsAtReject\": 1,\n  \"readdirCallsAfterReject\": 0\n}\n\n### Impact\n\nThis is an availability issue.\n\nApplications that expose globbing over attacker-influenced patterns or attacker-controlled directory trees and use AbortSignal / AbortSignal.timeout() as a traversal budget can still perform significant filesystem I/O and CPU work after a request has already timed out or been canceled.\n\nRepeated timed-out requests can stack background glob walks and degrade worker throughput or service availability.\n\nNo confidentiality or integrity impact was observed.","severity":"medium","score":6.3,"published":"2026-10-29T18:27:47.480Z","modified":"2026-10-30T23:15:04.503Z","withdrawn":false,"knownExploited":false,"affected":[{"ecosystem":"npm","name":"glob","sources":[{"name":"OSV · GHSA-3g3m-2fjr-6pw4","url":"https://osv.dev/vulnerability/GHSA-3g3m-2fjr-6pw4"}],"ranges":[{"events":[{"introduced":"9.0.0"},{"fixed":"14.0.2"}],"type":"SEMVER"}],"versions":[],"fixed":["14.0.2"]}],"sourceAffected":[],"references":["https://github.com/isaacs/node-glob/security/advisories/GHSA-3g3m-2fjr-6pw4","https://github.com/isaacs/node-glob/commit/4682e8c9babee1b385202ede36389634e12076d7","https://github.com/isaacs/node-glob/releases/tag/v14.0.2","https://nvd.nist.gov/vuln/detail/CVE-2026-118773","https://github.com/isaacs/node-glob"],"sources":[{"name":"CVE","id":"CVE-2026-118773","modified":"2026-10-30T17:12:23.906Z","url":"https://www.cve.org/CVERecord?id=CVE-2026-118773"},{"name":"OSV","id":"GHSA-3g3m-2fjr-6pw4","modified":"2026-10-30T23:15:04.503965732Z","url":"https://osv.dev/vulnerability/GHSA-3g3m-2fjr-6pw4"}],"assessments":[{"source":"GitHub_M","vector":"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","score":6.3},{"source":"OSV","vector":"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","score":6.3}],"cve":{"records":[{"id":"CVE-2026-118773","source":"GitHub_M","state":"PUBLISHED","reasons":[],"replacements":[],"disputed":false,"unsupportedWhenAssigned":false,"reserved":"2026-10-28T19:20:05.018Z","published":"2026-10-29T18:27:47.480Z","modified":"2026-10-30T17:12:23.906Z"}],"publishers":[{"name":"GitHub_M","role":"CNA","organizationId":"a0819718-46f1-4df5-94e2-005712e83aaa","modified":"2026-10-29T18:27:47.480Z"},{"name":"CISA-ADP","role":"ADP","organizationId":"134c704f-9b21-4f2e-91b3-4a467353bcc0","modified":"2026-10-30T17:12:23.906Z"}],"references":[{"url":"https://github.com/isaacs/node-glob/security/advisories/GHSA-3g3m-2fjr-6pw4","tags":["x_refsource_CONFIRM"],"source":"GitHub_M"},{"url":"https://github.com/isaacs/node-glob/commit/4682e8c9babee1b385202ede36389634e12076d7","tags":["x_refsource_MISC"],"source":"GitHub_M"},{"url":"https://github.com/isaacs/node-glob/releases/tag/v14.0.2","tags":["x_refsource_MISC"],"source":"GitHub_M"}],"weaknesses":[{"id":"CWE-400","description":"CWE-400: Uncontrolled Resource Consumption","source":"GitHub_M"}],"applicability":[],"prioritization":[{"source":"CISA-ADP","type":"SSVC","role":"CISA Coordinator","timestamp":"2026-10-30T15:20:35.333742Z","decisions":[{"name":"Exploitation","value":"none"},{"name":"Automatable","value":"no"},{"name":"Technical Impact","value":"partial"}]}]},"products":[{"vendor":"isaacs","name":"node-glob","platforms":[],"versions":[{"version":">= 9.0.0, < 14.0.2","status":"affected"}],"cpes":[],"source":"GitHub_M","url":"https://www.cve.org/CVERecord?id=CVE-2026-118773"}],"remediation":[],"observedAt":"2026-10-30T23:33:13.054Z","kev":{"status":"not-listed","checkedAt":"2026-10-31T03:00:34.533Z"},"coverage":[{"source":"NVD","status":"no-result","checkedAt":"2026-10-29T19:10:39.997Z","attemptedAt":"2026-10-29T19:10:39.997Z"},{"source":"GHSA","status":"no-result","checkedAt":"2026-10-29T19:10:38.853Z","attemptedAt":"2026-10-29T19:10:38.853Z"},{"source":"EUVD","status":"available","checkedAt":"2026-10-29T19:10:38.945Z","attemptedAt":"2026-10-29T19:10:38.945Z"},{"source":"EPSS","status":"no-result","checkedAt":"2026-10-29T19:10:40.428Z","attemptedAt":"2026-10-29T19:10:40.428Z"}],"evidence":[{"source":"ENISA EUVD","id":"EUVD-2026-113329","url":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-113329","modified":"Oct 29, 2026, 6:27:47 PM","score":6.3,"vector":"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","checkedAt":"2026-10-29T19:10:38.945Z"}],"aiSummary":{"text":"In glob versions 9.0.0 to 13.0.6, an AbortSignal cancellation bypass allows post-timeout filesystem traversal, potentially causing significant filesystem I/O and CPU work after a request has timed out or been canceled. The issue affects both glob() and globStream() functions. This is an availability issue.","model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","generatedAt":"2026-10-31T00:11:01.427Z","sources":[{"name":"CVE","url":"https://www.cve.org/CVERecord?id=CVE-2026-118773"},{"name":"OSV","url":"https://osv.dev/vulnerability/GHSA-3g3m-2fjr-6pw4"}]}}