CVE-2026-82417
Gravedad CVSS v4.0:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
30/08/2026
Última modificación:
30/08/2026
Descripción
*** Pendiente de traducción *** ### Summary<br />
<br />
<br />
<br />
`qs.stringify` throws a `TypeError` when it serializes an object whose own `constructor` property has a truthy, non-callable `isBuffer` member. `utils.isBuffer` duck-types buffers by calling `obj.constructor.isBuffer(obj)` after checking only that the property is truthy, so a value such as `{ constructor: { isBuffer: "x" } }` makes the call throw `TypeError: obj.constructor.isBuffer is not a function`.<br />
<br />
<br />
<br />
### Details<br />
<br />
<br />
<br />
`lib/stringify.js:127` calls `utils.isBuffer` on every non-primitive value it serializes. `utils.isBuffer` (`lib/utils.js:332`) reads `obj.constructor.isBuffer` and invokes it without verifying that it is a function. `constructor` and `isBuffer` are ordinary property names, so any object carrying them as own properties reaches the unchecked call.<br />
<br />
<br />
<br />
Such an object can be built from untrusted input. `qs.parse("x[constructor][isBuffer]=y", { plainObjects: true })` or `{ allowPrototypes: true }` keeps the `constructor` key as an own property (the default parse options drop it), and `JSON.parse("{\"a\":{\"constructor\":{\"isBuffer\":\"x\"}}}")` produces the same shape with no qs option involved. Express 4 with its default `query parser` setting and body-parser with `extended: true` both call `qs.parse` with `allowPrototypes: true`, so on those stacks `req.query` and `req.body` can carry the shape directly.<br />
<br />
<br />
<br />
#### PoC<br />
<br />
<br />
<br />
```js<br />
<br />
<br />
<br />
var qs = require("qs");<br />
<br />
<br />
<br />
qs.stringify(qs.parse("x[constructor][isBuffer]=y", { plainObjects: true }));<br />
<br />
<br />
<br />
qs.stringify(JSON.parse("{\"a\":{\"constructor\":{\"isBuffer\":\"x\"}}}"));<br />
<br />
<br />
<br />
// TypeError: obj.constructor.isBuffer is not a function<br />
<br />
<br />
<br />
// at Object.isBuffer (lib/utils.js:332:78)<br />
<br />
<br />
<br />
// at stringify (lib/stringify.js:127:45)<br />
<br />
<br />
<br />
```<br />
<br />
<br />
<br />
#### Fix<br />
<br />
<br />
<br />
`lib/utils.js`, applied in e83d321 on `main` and released as v6.16.0:<br />
<br />
<br />
<br />
```diff<br />
<br />
<br />
<br />
- return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));<br />
<br />
<br />
<br />
+ return !!(obj.constructor && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj));<br />
<br />
<br />
<br />
```<br />
<br />
<br />
<br />
Real `Buffer`, `safer-buffer`, and browserify `buffer` polyfill instances serialize exactly as before; only the throw is removed.<br />
<br />
<br />
<br />
### Affected versions<br />
<br />
<br />
<br />
`>=2.2.5
Impacto
Puntuación base 4.0
6.30
Gravedad 4.0
MEDIA
Puntuación base 3.x
5.30
Gravedad 3.x
MEDIA



