---
cve: "CVE-2026-82417"
severity: "MEDIUM"
cvss: 6.3
epss: "26%"
vendor: "ljharb"
kev: false
exploited: false
published: "2026-08-30 00:16:34"
tags: [cve, security, medium]
source: tsecurity.de CVE-Dossier
exported: "2026-08-31T21:10:22+02:00"
---

# CVE-2026-82417

> 6.3 MEDIUM · 🧪 PoC

## Beschreibung

### Summary



`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`.



### Details



`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.



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.



#### PoC



```js



var qs = require("qs");



qs.stringify(qs.parse("x[constructor][isBuffer]=y", { plainObjects: true }));



qs.stringify(JSON.parse("{\"a\":{\"constructor\":{\"isBuffer\":\"x\"}}}"));



// TypeError: obj.constructor.isBuffer is not a function



//     at Object.isBuffer (lib/utils.js:332:78)



//     at stringify (lib/stringify.js:127:45)



```



#### Fix



`lib/utils.js`, applied in e83d321 on `main` and released as v6.16.0:



```diff



- return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));



+ return !!(obj.constructor && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj));



```



Real `Buffer`, `safer-buffer`, and browserify `buffer` polyfill instances serialize exactly as before; only the throw is removed.



### Affected versions



`>=2.2.5

## CVSS-Vektor

```
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
```

| Metrik | Wert | Bewertung |
|---|---|---|
| AV Angriffsvektor | Netzwerk | bad |
| AC Komplexität | Gering | bad |
| PR Privilegien | Keine | bad |
| UI Interaktion | Keine | bad |

## Patch verfügbar (OSV)

- 18d085e919dae70c8f1b200ab99323058edab2c2 (Commit)
- e83d321ffafb38cf210683ac31714fce6ce1c6c6 (Commit)

## Referenzen

- <https://github.com/ljharb/qs/security/advisories/GHSA-4mjr-xmp4-gh2g>
- <https://github.com/ljharb/qs/commit/e83d321ffafb38cf210683ac31714fce6ce1c6c6>

---
_Exportiert aus dem [tsecurity.de CVE-Dossier](https://tsecurity.de/cve?cve=CVE-2026-82417) · Datenquellen: EUVD (ENISA), NVD, OSV, CISA KEV, FIRST EPSS, Exploit-DB, BSI BITS_
