CVE-2026-8723
Fecha de publicación:
17/05/2026
*** Pendiente de traducción *** ### Summary<br />
<br />
<br />
<br />
`qs.stringify` throws `TypeError` when called with `arrayFormat: &#39;comma&#39;` and `encodeValuesOnly: true` on an array containing `null` or `undefined`. The throw is synchronous and not handled by any of qs&#39;s null-related options (`skipNulls`, `strictNullHandling`).<br />
<br />
<br />
<br />
### Details<br />
<br />
<br />
<br />
In the comma + `encodeValuesOnly` branch, `lib/stringify.js:145` mapped the array through the raw encoder before joining:<br />
<br />
<br />
<br />
```js<br />
<br />
<br />
<br />
obj = utils.maybeMap(obj, encoder);<br />
<br />
<br />
<br />
```<br />
<br />
<br />
<br />
`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.<br />
<br />
<br />
<br />
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 #463, 2023-01-19), first released in v6.11.1.<br />
<br />
<br />
<br />
#### PoC<br />
<br />
<br />
<br />
```js<br />
<br />
<br />
<br />
const qs = require(&#39;qs&#39;);<br />
<br />
<br />
<br />
qs.stringify({ a: [null, &#39;b&#39;] }, { arrayFormat: &#39;comma&#39;, encodeValuesOnly: true });<br />
<br />
<br />
<br />
qs.stringify({ a: [undefined, &#39;b&#39;] }, { arrayFormat: &#39;comma&#39;, encodeValuesOnly: true });<br />
<br />
<br />
<br />
qs.stringify({ a: [null] }, { arrayFormat: &#39;comma&#39;, encodeValuesOnly: true });<br />
<br />
<br />
<br />
// TypeError: Cannot read properties of null (reading &#39;length&#39;)<br />
<br />
<br />
<br />
// at encode (lib/utils.js:195:13)<br />
<br />
<br />
<br />
// at Object.maybeMap (lib/utils.js:322:37)<br />
<br />
<br />
<br />
// at stringify (lib/stringify.js:145:25)<br />
<br />
<br />
<br />
```<br />
<br />
<br />
<br />
#### Fix<br />
<br />
<br />
<br />
`lib/stringify.js:145`, applied in 21f80b3 on `main` and released as v6.15.2:<br />
<br />
<br />
<br />
```diff<br />
<br />
<br />
<br />
- obj = utils.maybeMap(obj, encoder);<br />
<br />
<br />
<br />
+ obj = utils.maybeMap(obj, function (v) {<br />
<br />
<br />
<br />
+ return v == null ? v : encoder(v);<br />
<br />
<br />
<br />
+ });<br />
<br />
<br />
<br />
```<br />
<br />
<br />
<br />
`null` and `undefined` now pass through `maybeMap` unchanged and reach the `join(&#39;,&#39;)` step as-is. For `{ a: [null, &#39;b&#39;] }` 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(&#39;,&#39;) || null` and remain subject to `skipNulls` / `strictNullHandling` in the main loop.<br />
<br />
<br />
<br />
### Affected versions<br />
<br />
<br />
<br />
`>=6.11.1
Gravedad CVSS v4.0: MEDIA
Última modificación:
17/05/2026