Description
### 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 <6.16.0`, fixed in v6.16.0.
The unguarded duck-type was introduced in 3768a75 and first shipped in v2.2.5 (September 2014). v2.2.4 and earlier used `Buffer.isBuffer` and are not affected. Every release from v2.2.5 through v6.15.3 contains the unguarded call.
### Impact
An unauthenticated request can make any code path that re-serializes attacker-influenced data with `qs.stringify` (for example, rebuilding a query string from `req.query` for a redirect or an upstream request, or serializing a parsed JSON body) throw synchronously. In a typical Node.js HTTP framework the throw is caught by the framework error boundary and the affected request returns a 500; the process survives and other requests are unaffected. Where the call runs outside an error boundary, such as an `async` Express 4 handler (where the throw becomes an unhandled promise rejection) or a background job, the process exits, so the impact in that case depends on the application error handling rather than on qs.
Affected products
| Vendor | Product | Affected | Fixed |
|---|---|---|---|
| ljharb | qs | 2.2.5 – < 6.16.0 | 6.16.0 |
Fixed in Linux distributions
Distributions backport fixes, so the version that fixes this vulnerability differs per release — upgrade to at least the version shown. From the distributions' security trackers and advisories.
Debian
Security tracker ↗| Release | Package | Fixed in | Advisory |
|---|---|---|---|
| Debian 14 | node-qs | 6.16.0+ds+~6.15.1-1 | — |
| Debian 13 | node-qs | No fix yet | — |
| Debian 12 | node-qs | No fix yet | — |
Ubuntu
Security tracker ↗| Release | Package | Fixed in | Advisory |
|---|---|---|---|
| Ubuntu 26.10 | node-qs | No fix yet | — |
| Ubuntu 26.04 LTS | node-qs | No fix yet | — |
| Ubuntu 24.04 LTS | node-qs | No fix yet | — |
| Ubuntu 22.04 LTS | node-qs | No fix yet | — |
| Ubuntu 18.04 LTS | node-qs | No fix yet | — |
Show 3 more (older releases, extended support, other products)Fewer releases
| Release | Package | Fixed in | Advisory |
|---|---|---|---|
| Ubuntu 16.04 LTS | node-qs | No fix yet | — |
| Ubuntu Pro 20.04 LTS | node-qs | No fix yet | — |
| Ubuntu Pro 14.04 LTS | node-qs | No fix yet | — |
Red Hat
Security tracker ↗| Release | Package | Fixed in | Advisory |
|---|---|---|---|
| Red Hat Hardened Images 1 | grafana13.1 | 13.1.3-0.4.hum1 | RHSA-2026:62544 |
| Red Hat Hardened Images 1 | grafana13.2 | 13.2.1-0.1.hum1 | RHSA-2026:63164 |
Azure Linux
| Release | Package | Fixed in | Advisory |
|---|---|---|---|
| Azure Linux 3 | js-jquery +2 | No fix yet | — |
Wolfi
| Release | Package | Fixed in | Advisory |
|---|---|---|---|
| Wolfi rolling | argo-workflows-ui-4.0 | 4.0.11-r0 | — |
| Wolfi rolling | code-server | 4.135.0-r2 | — |
| Wolfi rolling | json-server | 0.17.4-r13 | — |
| Wolfi rolling | jupyter-base-notebook | 7.6.3-r2 | — |
| Wolfi rolling | kubeflow-centraldashboard | 2.0.0-r2 | — |
| Wolfi rolling | langfuse-3 +1 | 3.225.7-r1 | — |
| Wolfi rolling | langfuse-3-compat | 3.225.7-r6 | — |
| Wolfi rolling | opensearch-dashboards-3 | 3.8.0-r2 | — |
| Wolfi rolling | opensearch-dashboards-3-dashboards-maps +11 | 3.8.0-r1 | — |
| Wolfi rolling | prism | 5.16.0-r8 | — |
| Wolfi rolling | renovate | 44.69.8-r0 | — |
| Wolfi rolling | sqlpad | 7.5.7-r36 | — |
| Wolfi rolling | tileserver-gl | 5.6.0-r14 | — |
Affected packages
| Ecosystem | Package | Affected | Fixed | Record |
|---|---|---|---|---|
| npm | qs | >= 2.2.5, < 6.16.0 | 6.16.0 | GHSA-4mjr-xmp4-gh2g |
Advisories 6
- RHSA-2026:63164 Red Hat Security Advisory: Red Hat Hardened Images RPMs bug fix and enhancement update Red Hat Security Advisories (RHSA) · Nov 13, 2026
- WID-SEC-2026-3498 Red Hat OpenShift Container Platform (opentelemetry-go, qs.stringify): Mehrere Schwachstellen ermöglichen Denial of Service BSI CERT-Bund (WID) · Nov 12, 2026
- WID-SEC-2026-3596 IBM App Connect Enterprise: Mehrere Schwachstellen BSI CERT-Bund (WID) · Nov 10, 2026
- RHSA-2026:62544 Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update Red Hat Security Advisories (RHSA) · Oct 20, 2026
- WID-SEC-2026-3623 IBM DataPower Gateway: Mehrere Schwachstellen BSI CERT-Bund (WID) · Oct 18, 2026
- NCSC-2026-0431 Kwetsbaarheden verholpen in IBM DataPower Gateway en onderliggende componenten NCSC-NL (Netherlands) · Oct 16, 2026