Repository navigation
Move to stream-json 3 for CVE-2026-71429 - #554
alexandrucojocaru-creatopy wants to merge 1 commit into
Conversation
stream-json <= 3.4.0 has a quadratic-time denial of service in its path filters (GHSA-528h-pc64-c93x). This library only uses the parser and streamArray, which are not affected, but every install still pulls in a vulnerable stream-json 1.x and gets flagged for it. stream-json 3 is ESM-only and changed its API: - `new Parser(options)` becomes `parser.asStream(options)`, and `streamArray()` becomes `streamArray.asStream()`, imported from `stream-json/streamers/stream-array.js`. - stream-chain, which customer.ts imports directly, is now declared (^4.2.6) instead of arriving through stream-json. - The CJS build loads both packages with require(esm), which Node enables without a flag from 22.12, so engines moves from >=22 to >=22.12. - Neither tsconfig resolves types through package `exports`, so src/stream-json.d.ts points the streamer subpath at its file. - Jest compiles the two ESM packages to CommonJS for tests. New tests pin the error path every failed query() takes (handleStreamError): a GoogleAdsFailure with details, an API message without details, and a non-JSON body. They pass unchanged on stream-json 1.9.1 and 3.7.0. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
@Lewis-Clayton @avermeil could one of you approve the workflow run and review this when you have a moment? It moves the library to stream-json 3, so installs stop pulling in a stream-json flagged by CVE-2026-71429. The library itself only uses the unaffected parser and streamArray. The Node 22/24 tests, |
|
Thanks @alexandrucojocaru-creatopy, always appreciate a PR. We can't support change at this time. The library only uses the parser and |
Why
stream-json<= 3.4.0 has a quadratic-time denial of service in its path filters:pick,ignore,filterandreplace(GHSA-528h-pc64-c93x, CVE-2026-71429). The fix is only in 3.5.0 and later; there is no 1.x or 2.x backport.This library uses only the parser and
streamArray, which the advisory lists as not affected. It still pinsstream-json ^1.8.0, though, so every project that depends ongoogle-ads-apigets a vulnerable version installed and flagged by Dependabot. Downstream projects can't fix this with an override:stream-json3 is ESM-only and renamed the modules this library requires, so an override breaksgoogle-ads-apias soon as it loads.Changes
src/customer.ts: the twostream-jsonpipelines, instreamerandhandleStreamError, move to the 3.x API.new Parser(options)→parser.asStream(options)streamArray()→streamArray.asStream(), fromstream-json/streamers/stream-array.jspackage.json:stream-json^1.8.0→^3.7.0.stream-chain^4.2.6is now declared.customer.tsimports it directly but only received it throughstream-json1.x.@types/stream-jsonis removed, because 3.x ships its own types.engines.nodegoes from>=22to>=22.12. The CommonJS build loads these ESM-only packages withrequire(), which Node enables without a flag from 22.12. On 22.0–22.11 it fails withERR_REQUIRE_ESM.src/stream-json.d.ts:stream-json3 publishes its streamers only through itsexportsmap ("./*": "./src/*"). Neither tsconfig resolves types throughexports: the CJS build uses node10 resolution, and the ESM build setsresolvePackageJsonExports: false. This declaration points the one subpath's types at its file, and Node resolves the runtime import through the map. Nothing reaches the published.d.ts, because the stream types aren't part of the public API.jest.config.js: compilesstream-jsonandstream-chainto CommonJS for tests only, since Jest 29's CommonJS runtime can't load ES modules. Neither package usesimport.metaor top-level await.src/customer.spec.ts: three new tests forhandleStreamError, the path every failedquery()takes:GoogleAdsFailureparsed from the error details;Verification
master(stream-json1.9.1) and on this branch (3.7.0).streamArrayfrom the report pipeline fails thereportStreamtests;searchStreambodies across six seeds. They included result batches, summary rows, error bodies, and truncated or malformed JSON, split at random byte boundaries, including inside multi-byte characters. The yielded values, the first error value, and the failure behaviour were identical in every case. A deliberately wrong parser option in the same harness matched only 15 of 100 cases.yarn lintpasses;yarn testpasses (200 tests: the 197 existing plus the 3 new);yarn test:packagepasses.@arethetypeswrong/cli --profile node16 --pack .passes.build/*/customer.jsboth load and import the new modules.tsc -p tsconfig.jsonstill reports one error, TS2769 inscripts/services.ts, which this change doesn't touch. The published builds usetsconfig.cjs.jsonandtsconfig.esm.json, and both compile cleanly.🤖 Generated with Claude Code