Skip to content

Commit e277daa

Browse files
fix(security): update dependency qs to v6.15.2 [security] (#1390)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [qs](https://redirect.github.com/ljharb/qs) | [`6.15.1` → `6.15.2`](https://renovatebot.com/diffs/npm/qs/6.15.1/6.15.2) | ![age](https://developer.mend.io/api/mc/badges/age/npm/qs/6.15.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/qs/6.15.1/6.15.2?slim=true) | --- ### qs has a remotely triggerable DoS: qs.stringify crashes with TypeError on null/undefined entries in comma-format arrays when encodeValuesOnly is set [CVE-2026-8723](https://nvd.nist.gov/vuln/detail/CVE-2026-8723) / [GHSA-q8mj-m7cp-5q26](https://redirect.github.com/advisories/GHSA-q8mj-m7cp-5q26) <details> <summary>More information</summary> #### Details ##### Summary `qs.stringify` throws `TypeError` when called with `arrayFormat: 'comma'` and `encodeValuesOnly: true` on an array containing `null` or `undefined`. The throw is synchronous and not handled by any of qs's null-related options (`skipNulls`, `strictNullHandling`). ##### Details In the comma + `encodeValuesOnly` branch, `lib/stringify.js:145` mapped the array through the raw encoder before joining: ```js obj = utils.maybeMap(obj, encoder); ``` `utils.encode` (`lib/utils.js:195`) reads `str.length` with no null guard, so a `null` or `undefined` element throws `TypeError`. `skipNulls` and `strictNullHandling` are both checked in the per-element loop below this line and never get a chance to run. Same class of bug as the filter-array path fixed in 0c180a4. The vulnerable shape of the comma + `encodeValuesOnly` branch was introduced in 4c4b23d ("encode comma values more consistently", PR #&#8203;463, 2023-01-19), first released in v6.11.1. ##### PoC ```js const qs = require('qs'); qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }); // TypeError: Cannot read properties of null (reading 'length') // at encode (lib/utils.js:195:13) // at Object.maybeMap (lib/utils.js:322:37) // at stringify (lib/stringify.js:145:25) ``` ##### Fix `lib/stringify.js:145`, applied in 21f80b3 on `main`: ```diff - obj = utils.maybeMap(obj, encoder); + obj = utils.maybeMap(obj, function (v) { + return v == null ? v : encoder(v); + }); ``` `null` and `undefined` now pass through `maybeMap` unchanged and reach the `join(',')` step as-is. For `{ a: [null, 'b'] }` this produces `a=,b`, matching the non-`encodeValuesOnly` comma path (which already joins before encoding and produces `a=%2Cb` for the same input). Single-element `[null]` arrays still collapse via the existing `obj.join(',') || null` and remain subject to `skipNulls` / `strictNullHandling` in the main loop. ##### Affected versions `>=6.11.1 <=6.15.1` The vulnerable code shape was introduced in 4c4b23d and first shipped in v6.11.1. Earlier versions — including all of 6.7.x, 6.8.x, 6.9.x, 6.10.x, and 6.11.0 — implemented the comma + `encodeValuesOnly` path differently (joining before encoding) and are not affected. Empirically verified across released versions. ##### Impact Application code that calls `qs.stringify` with both `arrayFormat: 'comma'` and `encodeValuesOnly: true` (both non-default) on input that may contain a `null` or `undefined` array element will throw synchronously instead of producing a query string. In a typical Node.js HTTP framework (Express, Fastify, Koa, hapi) the sync throw is caught by the framework's error boundary and the affected request returns a 500; the worker process does not exit and subsequent requests are unaffected. The "kills the worker process" framing applies only to call sites outside a request-handler error boundary (background jobs, startup paths, stream pipelines) or to deployments with framework error handling explicitly disabled. The vulnerable input is a `null` or `undefined` entry inside an array; this is reachable from JSON request bodies or from application code constructing arrays from user input, but not from standard HTML form submissions (which produce strings or omitted fields, not literal `null`). #### Severity - CVSS Score: 6.3 / 10 (Medium) - Vector String: `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` #### References - [https://github.com/ljharb/qs/security/advisories/GHSA-q8mj-m7cp-5q26](https://redirect.github.com/ljharb/qs/security/advisories/GHSA-q8mj-m7cp-5q26) - [https://nvd.nist.gov/vuln/detail/CVE-2026-8723](https://nvd.nist.gov/vuln/detail/CVE-2026-8723) - [https://github.com/ljharb/qs/commit/21f80b33e5c8b3f7eba1034fff0da4a4a37a1d41](https://redirect.github.com/ljharb/qs/commit/21f80b33e5c8b3f7eba1034fff0da4a4a37a1d41) - [https://github.com/advisories/GHSA-q8mj-m7cp-5q26](https://redirect.github.com/advisories/GHSA-q8mj-m7cp-5q26) This data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-q8mj-m7cp-5q26) ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Release Notes <details> <summary>ljharb/qs (qs)</summary> ### [`v6.15.2`](https://redirect.github.com/ljharb/qs/blob/HEAD/CHANGELOG.md#6152) [Compare Source](https://redirect.github.com/ljharb/qs/compare/v6.15.1...v6.15.2) - \[Fix] `stringify`: skip null/undefined entries in `arrayFormat: 'comma'` + `encodeValuesOnly` instead of crashing in `encoder` - \[Fix] `stringify`: use configured `delimiter` after `charsetSentinel` ([#&#8203;555](https://redirect.github.com/ljharb/qs/issues/555)) - \[Fix] `stringify`: apply `formatter` to encoded key under `strictNullHandling` ([#&#8203;554](https://redirect.github.com/ljharb/qs/issues/554)) - \[Fix] `stringify`: skip null/undefined filter-array entries instead of crashing in `encoder` ([#&#8203;551](https://redirect.github.com/ljharb/qs/issues/551)) - \[Fix] `parse`: handle nested bracket groups and add regression tests ([#&#8203;530](https://redirect.github.com/ljharb/qs/issues/530)) - \[readme] fix grammar ([#&#8203;550](https://redirect.github.com/ljharb/qs/issues/550)) - \[Dev Deps] update `@ljharb/eslint-config` - \[Tests] add regression tests for keys containing percent-encoded bracket text </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/open-feature/openfeature.dev). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent 0c1756d commit e277daa

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15537,11 +15537,11 @@ __metadata:
1553715537
linkType: hard
1553815538

1553915539
"qs@npm:^6.14.2":
15540-
version: 6.15.1
15541-
resolution: "qs@npm:6.15.1"
15540+
version: 6.15.2
15541+
resolution: "qs@npm:6.15.2"
1554215542
dependencies:
1554315543
side-channel: "npm:^1.1.0"
15544-
checksum: 10c0/19ee504f0ebff72598503e38cd6d9bd7b52a8ab62ae18b1e6bee3d4db58469bd65871ef1893a881bafb0f80ef2f9ab586e1f255cf25cc8d816c0f5a704721d97
15544+
checksum: 10c0/e6fd5f6f0aab06d480fe9ab15cebfc4ce4235303e2f91dc69a8f7f4df1e668a61c11d1cfbabacf4295cbbeb7b670ed23db45307480726259761f98e5695e93a7
1554515545
languageName: node
1554615546
linkType: hard
1554715547

0 commit comments

Comments
 (0)