CVE-2026-82417
qs.stringify throws TypeError on objects with a non-callable constructor.isBuffer property
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
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:
- 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.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
6.3
qs.stringify throws TypeError on objects with a non-callable constructor.isBuffer property
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
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:
- 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.
- Record
CVE-2026-82417- CVSS 4.0
- 6.3 Medium
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 - CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-248, CWE-703
- Updated
- 2026-11-02
EUVDEUVD-2026-68140
6.3
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
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:
- 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.
- Record
EUVD-2026-68140- CVSS 4.0
- 6.3 Medium
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 - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-4mjr-xmp4-gh2g
6.3
qs: Denial of Service via Attacker Controlled isBuffer
Summary
qs.stringify() calls utils.isBuffer() on every value it serializes, and utils.isBuffer() invokes obj.constructor.isBuffer(obj) without checking that it is callable. A value whose own constructor.isBuffer is a non-function makes qs call a non-callable and throw TypeError. Such a value is produced by qs.parse itself from an untrusted query string when plainObjects: true or allowPrototypes: true is set, so a pure-qs parse → stringify round-trip — no JSON.parse — turns an unauthenticated query string into an uncaught throw.
An attacker-controlled parse input reaches the host application's availability asset — via qs's own recommended plainObjects mitigation — and triggers an uncaught exception during a parse → stringify round-trip.
Details
utils.isBuffer runs at lib/stringify.js:127 for every serialized value:
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { ... }
utils.isBuffer (lib/utils.js:327-333) invokes obj.constructor.isBuffer without verifying it is callable:
var isBuffer = function isBuffer(obj) {
if (!obj || typeof obj !== 'object') { return false; }
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
};
constructor and isBuffer are ordinary keys. qs.parse with plainObjects: true or allowPrototypes: true keeps them as own properties, so the parsed value carries a non-function constructor.isBuffer; stringify then calls a non-callable and throws TypeError. By contrast utils.isRegExp uses a brand check (Object.prototype.toString); the missing guard here is an internal inconsistency, not a platform limitation.
Trust Boundary Note
qs.stringify alone treats its input as caller-constructed, so serializing a hostile object could be argued outside its contract. This report does not depend on that framing: the malicious shape is produced by qs.parse, whose input is untrusted by design. qs.parse normally strips a constructor key via its prototype guard, but with the documented options plainObjects: true or allowPrototypes: true the key survives and lands as an own property. Feeding the parsed object back into qs.stringify — the standard round-trip in gateways and request-forwarders — then hits the unchecked call.
PoC
poc02c_isBuffer_qs_only_roundtrip.js — pure-qs chain, no JSON.parse; an untrusted query string alone reaches the throw:
'use strict';
var qs = require('qs');
var untrustedQueryString = 'x%5Bconstructor%5D%5BisBuffer%5D=y'; // x[constructor][isBuffer]=y
var parsed = qs.parse(untrustedQueryString, { plainObjects: true });
console.log('[parse] kept constructor key:', JSON.stringify(parsed));
try {
qs.stringify(parsed);
console.log('[stringify] no throw (unexpected)');
} catch (e) {
console.log('[stringify] DoS reproduced ->', e.constructor.name + ':', e.message);
}
poc02_isBuffer.js — the minimal defect:
'use strict';
var qs = require('qs');
try {
qs.stringify(JSON.parse('{"a":{"constructor":{"isBuffer":"x"}}}'));
} catch (e) {
console.log('[A] DoS reproduced ->', e.constructor.name + ':', e.message);
}
poc02b_isBuffer_async_crash.js — worker death in an async sink:
'use strict';
var qs = require('qs');
function handleRequestAsync(clientJsonBody) {
try {
setImmediate(function () { // async continuation, outside the try
qs.stringify(JSON.parse(clientJsonBody)); // throws here, uncaught
});
console.log('[handler] returned 200 synchronously; async work scheduled');
} catch (e) {
console.log('[handler] caught synchronously (will NOT happen):', e.message);
}
}
process.on('exit', function (code) {
console.log('[proc] process exiting with code:', code);
});
handleRequestAsync('{"filters":{"constructor":{"isBuffer":"x"}}}');
Execution Steps
cd poc
npm…
- Record
GHSA-4mjr-xmp4-gh2g- CVSS 4.0
- 6.3 Medium
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 - CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-248, CWE-703
- Updated
- 2026-11-02
NVD
6.3
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
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:
- 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.
- Record
CVE-2026-82417- CVSS 4.0
- 6.3 Medium
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-248, CWE-703
- Updated
- 2026-11-02
OSV
6.3
qs.stringify throws TypeError on objects with a non-callable constructor.isBuffer property
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
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:
- 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.
- Record
CVE-2026-82417- CVSS 4.0
- 6.3 Medium
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 - Weakness
- CWE-248, CWE-703
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-82417
6.3
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.
- Record
DEBIAN-CVE-2026-82417- CVSS 4.0
- 6.3 Medium
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Updated
- 2026-11-02
Show 25 moreShow less
OSVGHSA-4mjr-xmp4-gh2g
6.3
qs: Denial of Service via Attacker Controlled isBuffer
Summary
qs.stringify() calls utils.isBuffer() on every value it serializes, and utils.isBuffer() invokes obj.constructor.isBuffer(obj) without checking that it is callable. A value whose own constructor.isBuffer is a non-function makes qs call a non-callable and throw TypeError. Such a value is produced by qs.parse itself from an untrusted query string when plainObjects: true or allowPrototypes: true is set, so a pure-qs parse → stringify round-trip — no JSON.parse — turns an unauthenticated query string into an uncaught throw.
An attacker-controlled parse input reaches the host application's availability asset — via qs's own recommended plainObjects mitigation — and triggers an uncaught exception during a parse → stringify round-trip.
Details
utils.isBuffer runs at lib/stringify.js:127 for every serialized value:
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { ... }
utils.isBuffer (lib/utils.js:327-333) invokes obj.constructor.isBuffer without verifying it is callable:
var isBuffer = function isBuffer(obj) {
if (!obj || typeof obj !== 'object') { return false; }
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
};
constructor and isBuffer are ordinary keys. qs.parse with plainObjects: true or allowPrototypes: true keeps them as own properties, so the parsed value carries a non-function constructor.isBuffer; stringify then calls a non-callable and throws TypeError. By contrast utils.isRegExp uses a brand check (Object.prototype.toString); the missing guard here is an internal inconsistency, not a platform limitation.
Trust Boundary Note
qs.stringify alone treats its input as caller-constructed, so serializing a hostile object could be argued outside its contract. This report does not depend on that framing: the malicious shape is produced by qs.parse, whose input is untrusted by design. qs.parse normally strips a constructor key via its prototype guard, but with the documented options plainObjects: true or allowPrototypes: true the key survives and lands as an own property. Feeding the parsed object back into qs.stringify — the standard round-trip in gateways and request-forwarders — then hits the unchecked call.
PoC
poc02c_isBuffer_qs_only_roundtrip.js — pure-qs chain, no JSON.parse; an untrusted query string alone reaches the throw:
'use strict';
var qs = require('qs');
var untrustedQueryString = 'x%5Bconstructor%5D%5BisBuffer%5D=y'; // x[constructor][isBuffer]=y
var parsed = qs.parse(untrustedQueryString, { plainObjects: true });
console.log('[parse] kept constructor key:', JSON.stringify(parsed));
try {
qs.stringify(parsed);
console.log('[stringify] no throw (unexpected)');
} catch (e) {
console.log('[stringify] DoS reproduced ->', e.constructor.name + ':', e.message);
}
poc02_isBuffer.js — the minimal defect:
'use strict';
var qs = require('qs');
try {
qs.stringify(JSON.parse('{"a":{"constructor":{"isBuffer":"x"}}}'));
} catch (e) {
console.log('[A] DoS reproduced ->', e.constructor.name + ':', e.message);
}
poc02b_isBuffer_async_crash.js — worker death in an async sink:
'use strict';
var qs = require('qs');
function handleRequestAsync(clientJsonBody) {
try {
setImmediate(function () { // async continuation, outside the try
qs.stringify(JSON.parse(clientJsonBody)); // throws here, uncaught
});
console.log('[handler] returned 200 synchronously; async work scheduled');
} catch (e) {
console.log('[handler] caught synchronously (will NOT happen):', e.message);
}
}
process.on('exit', function (code) {
console.log('[proc] process exiting with code:', code);
});
handleRequestAsync('{"filters":{"constructor":{"isBuffer":"x"}}}');
Execution Steps
cd poc
npm…
- Record
GHSA-4mjr-xmp4-gh2g- CVSS 4.0
- 6.3 Medium
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 - CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-248, CWE-703
- Updated
- 2026-11-02
OSVRHSA-2026:62544
7.5
Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update
- Record
RHSA-2026:62544- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVRHSA-2026:63164
8.8
Red Hat Security Advisory: Red Hat Hardened Images RPMs bug fix and enhancement update
- Record
RHSA-2026:63164- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-82417
6.3
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.
- Record
UBUNTU-CVE-2026-82417- CVSS 4.0
- 6.3 Medium
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 - CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
OSVAZL-98331 No score
CVE-2026-82417 affecting package js-jquery 3.5.0-4
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
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:
- 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.
- Record
AZL-98331- Updated
- 2026-11-05
OSVAZL-98334 No score
CVE-2026-82417 affecting package nodejs-nodemon 2.0.3-5
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
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:
- 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.
- Record
AZL-98334- Updated
- 2026-11-05
OSVAZL-98397 No score
CVE-2026-82417 affecting package python-tensorboard 2.16.2-6
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
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:
- 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.
- Record
AZL-98397- Updated
- 2026-11-02
OSVCLSA-2026-1788167376 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 6.14.0-tuxcare.2.
- Record
CLSA-2026-1788167376- Updated
- 2026-11-02
OSVCLSA-2026-1790178011 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 5.2.1-tuxcare.3.
- Record
CLSA-2026-1790178011- Updated
- 2026-11-02
OSVCLSA-2026-1790183894 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 6.2.6-tuxcare.1.
- Record
CLSA-2026-1790183894- Updated
- 2026-11-02
OSVCLSA-2026-1790183896 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 6.4.3-tuxcare.1.
- Record
CLSA-2026-1790183896- Updated
- 2026-11-02
OSVCLSA-2026-1790521454 No score
TuxCare security update for qs (2 CVEs)
TuxCare rebuilt qs to address 2 CVEs. Fixed in 6.13.0-tuxcare.1.
- Record
CLSA-2026-1790521454- Updated
- 2026-11-02
OSVCLSA-2026-1790541933 No score
TuxCare security update for qs (2 CVEs)
TuxCare rebuilt qs to address 2 CVEs. Fixed in 6.15.3-tuxcare.1.
- Record
CLSA-2026-1790541933- Updated
- 2026-11-02
OSVCLSA-2026-1792074695 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 2.3.3-tuxcare.2.
- Record
CLSA-2026-1792074695- Updated
- 2026-11-02
OSVCLSA-2026-1792074756 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 2.2.5-tuxcare.2.
- Record
CLSA-2026-1792074756- Updated
- 2026-11-02
OSVCLSA-2026-1792074861 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 3.1.0-tuxcare.4.
- Record
CLSA-2026-1792074861- Updated
- 2026-11-02
OSVCLSA-2026-1792074917 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 2.4.2-tuxcare.4.
- Record
CLSA-2026-1792074917- Updated
- 2026-11-02
OSVCLSA-2026-1792164286 No score
TuxCare security update for qs (3 CVEs)
TuxCare rebuilt qs to address 3 CVEs. Fixed in 6.11.2-tuxcare.1.
- Record
CLSA-2026-1792164286- Updated
- 2026-11-02
OSVCLSA-2026-1792447268 No score
TuxCare security update for qs (3 CVEs)
TuxCare rebuilt qs to address 3 CVEs. Fixed in 6.5.1-tuxcare.1.
- Record
CLSA-2026-1792447268- Updated
- 2026-11-02
OSVCLSA-2026-1792449761 No score
TuxCare security update for qs (3 CVEs)
TuxCare rebuilt qs to address 3 CVEs. Fixed in 6.14.2-tuxcare.1.
- Record
CLSA-2026-1792449761- Updated
- 2026-11-02
OSVCLSA-2026-1792476180 No score
TuxCare security update for qs (4 CVEs)
TuxCare rebuilt qs to address 4 CVEs. Fixed in 6.2.1-tuxcare.1.
- Record
CLSA-2026-1792476180- Updated
- 2026-11-02
OSVCLSA-2026-1792763694 No score
TuxCare security update for qs (2 CVEs)
TuxCare rebuilt qs to address 2 CVEs. Fixed in 6.5.3-tuxcare.2.
- Record
CLSA-2026-1792763694- Updated
- 2026-11-02
OSVCLSA-2026-1793098775 No score
TuxCare security update for qs (1 CVE)
TuxCare rebuilt qs to address 1 CVE. Fixed in 6.10.4-tuxcare.2.
- Record
CLSA-2026-1793098775- Updated
- 2026-11-02
OSVCLSA-2026-1794058800 No score
TuxCare security update for qs (2 CVEs)
TuxCare rebuilt qs to address 2 CVEs. Fixed in 6.9.6-tuxcare.1.
- Record
CLSA-2026-1794058800- Updated
- 2026-11-07
OSVCLSA-2026-1794060891 No score
TuxCare security update for qs (2 CVEs)
TuxCare rebuilt qs to address 2 CVEs. Fixed in 6.9.1-tuxcare.1.
- Record
CLSA-2026-1794060891- Updated
- 2026-11-07
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
qsnpm |
2.2.5 up to 6.16.0 | 6.16.0 |
js-jqueryAzure Linux:3 |
through 3.5.0-4 | None known |
nodejs-nodemonAzure Linux:3 |
through 2.0.3-5 | None known |
python-tensorboardAzure Linux:3 |
through 2.16.2-6 | None known |
qsTuxCare:npm |
6.14.0-tuxcare.0 up to 6.14.0-tuxcare.2, plus listed versions 6.14.06.14.0-tuxcare.1 |
6.14.0-tuxcare.2 |
qsTuxCare:npm |
5.2.1-tuxcare.0 up to 5.2.1-tuxcare.3, plus listed versions 5.2.15.2.1-tuxcare.15.2.1-tuxcare.2 |
5.2.1-tuxcare.3 |
qsTuxCare:npm |
6.2.6-tuxcare.0 up to 6.2.6-tuxcare.1, plus listed versions 6.2.6 |
6.2.6-tuxcare.1 |
qsTuxCare:npm |
6.4.3-tuxcare.0 up to 6.4.3-tuxcare.1, plus listed versions 6.4.3 |
6.4.3-tuxcare.1 |
qsTuxCare:npm From an advisory covering 2 CVEs |
6.13.0-tuxcare.0 up to 6.13.0-tuxcare.1, plus listed versions 6.13.0 |
6.13.0-tuxcare.1 |
qsTuxCare:npm From an advisory covering 2 CVEs |
6.15.3-tuxcare.0 up to 6.15.3-tuxcare.1, plus listed versions 6.15.3 |
6.15.3-tuxcare.1 |
Show 25 moreShow less
| Package | Affected | Fixed |
|---|---|---|
qsTuxCare:npm |
2.3.3-tuxcare.0 up to 2.3.3-tuxcare.2, plus listed versions 2.3.32.3.3-tuxcare.1 |
2.3.3-tuxcare.2 |
qsTuxCare:npm |
2.2.5-tuxcare.0 up to 2.2.5-tuxcare.2, plus listed versions 2.2.52.2.5-tuxcare.1 |
2.2.5-tuxcare.2 |
qsTuxCare:npm |
3.1.0-tuxcare.0 up to 3.1.0-tuxcare.4, plus listed versions 3.1.03.1.0-tuxcare.13.1.0-tuxcare.23.1.0-tuxcare.3 |
3.1.0-tuxcare.4 |
qsTuxCare:npm |
2.4.2-tuxcare.0 up to 2.4.2-tuxcare.4, plus listed versions 2.4.22.4.2-tuxcare.12.4.2-tuxcare.22.4.2-tuxcare.3 |
2.4.2-tuxcare.4 |
qsTuxCare:npm From an advisory covering 3 CVEs |
6.11.2-tuxcare.0 up to 6.11.2-tuxcare.1, plus listed versions 6.11.2 |
6.11.2-tuxcare.1 |
qsTuxCare:npm From an advisory covering 3 CVEs |
6.5.1-tuxcare.0 up to 6.5.1-tuxcare.1, plus listed versions 6.5.1 |
6.5.1-tuxcare.1 |
qsTuxCare:npm From an advisory covering 3 CVEs |
6.14.2-tuxcare.0 up to 6.14.2-tuxcare.1, plus listed versions 6.14.2 |
6.14.2-tuxcare.1 |
qsTuxCare:npm From an advisory covering 4 CVEs |
6.2.1-tuxcare.0 up to 6.2.1-tuxcare.1, plus listed versions 6.2.1 |
6.2.1-tuxcare.1 |
qsTuxCare:npm From an advisory covering 2 CVEs |
6.5.3-tuxcare.0 up to 6.5.3-tuxcare.2, plus listed versions 6.5.36.5.3-tuxcare.1 |
6.5.3-tuxcare.2 |
qsTuxCare:npm |
6.10.4-tuxcare.0 up to 6.10.4-tuxcare.2, plus listed versions 6.10.46.10.4-tuxcare.1 |
6.10.4-tuxcare.2 |
qsTuxCare:npm From an advisory covering 2 CVEs |
6.9.6-tuxcare.0 up to 6.9.6-tuxcare.1, plus listed versions 6.9.6 |
6.9.6-tuxcare.1 |
qsTuxCare:npm From an advisory covering 2 CVEs |
6.9.1-tuxcare.0 up to 6.9.1-tuxcare.1, plus listed versions 6.9.1 |
6.9.1-tuxcare.1 |
node-qsDebian:12 |
All versions, plus listed versions 6.11.0+ds+~6.9.7-36.11.0+ds+~6.9.7-46.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-16.15.0+ds+~6.15.0-1 Show 4 moreShow less6.15.0+ds+~6.15.0-26.15.0+ds+~6.15.0-36.15.2+ds+~6.15.1-16.16.0+ds+~6.15.1-1 |
None known |
node-qsDebian:13 |
All versions, plus listed versions 6.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-16.15.0+ds+~6.15.0-16.15.0+ds+~6.15.0-26.15.0+ds+~6.15.0-36.15.2+ds+~6.15.1-16.16.0+ds+~6.15.1-1 |
None known |
node-qsDebian:14 |
before 6.16.0+ds+~6.15.1-1, plus listed versions 6.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-16.15.0+ds+~6.15.0-16.15.0+ds+~6.15.0-26.15.0+ds+~6.15.0-36.15.2+ds+~6.15.1-1 |
6.16.0+ds+~6.15.1-1 |
grafana13.1Red Hat:hummingbird:1 From an advisory covering 2 CVEs |
before 0:13.1.3-0.4.hum1 | 0:13.1.3-0.4.hum1 |
grafana13.2Red Hat:hummingbird:1 From an advisory covering 10 CVEs |
before 0:13.2.1-0.1.hum1 | 0:13.2.1-0.1.hum1 |
node-qsUbuntu:Pro:14.04:LTS |
All versions, plus listed versions 0.4.2-10.6.5-10.6.5-1ubuntu0.1~esm1 |
None known |
node-qsUbuntu:16.04:LTS |
All versions, plus listed versions 2.2.4-1 |
None known |
node-qsUbuntu:18.04:LTS |
All versions, plus listed versions 2.2.4-12.2.4-1ubuntu1 |
None known |
node-qsUbuntu:Pro:20.04:LTS |
All versions, plus listed versions 6.5.2-16.9.0+ds-16.9.1+ds-16.9.1+ds-1ubuntu0.1~esm1 |
None known |
node-qsUbuntu:22.04:LTS |
All versions, plus listed versions 6.9.4+ds-16.10.1+ds-16.10.2+ds+~6.9.7-16.10.3+ds+~6.9.7-1 |
None known |
node-qsUbuntu:24.04:LTS |
All versions, plus listed versions 6.11.0+ds+~6.9.7-36.11.0+ds+~6.9.7-4 |
None known |
node-qsUbuntu:26.10 |
All versions, plus listed versions 6.14.1+ds+~6.14.0-16.15.2+ds+~6.15.1-1 |
None known |
node-qsUbuntu:26.04:LTS |
All versions, plus listed versions 6.13.0+ds+~6.9.16-16.14.1+ds+~6.14.0-1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases | OSV | |
| affected | ||
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-82417 is a medium vulnerability (CVSS 6.3) in Ljharb Qs, published August 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.40%, the 34th percentile. Fixed in qs 6.16.0.
References
github.com/ljharb/qs/security/advisories/GHSA-4mjr-xmp4-gh2g
github.com/ljharb/qs/commit/e83d321ffafb38cf210683ac31714fce6ce1c6c6
nvd.nist.gov/vuln/detail/CVE-2026-82417
github.com/advisories/GHSA-4mjr-xmp4-gh2g
npmjs.com/qs
github.com/CVEProject/cvelistV5/tree/main/cves/2026/82xxx/CVE-2026-82417.json
Show 65 moreShow less
github.com/ljharb/qs
security-tracker.debian.org/tracker/CVE-2026-82417
access.redhat.com/errata/RHSA-2026:62544
access.redhat.com/security/cve/CVE-2026-82417
access.redhat.com/security/cve/CVE-2026-82562
access.redhat.com/security/updates/classification
images.redhat.com
security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_62544.json
bugzilla.redhat.com/show_bug.cgi?id=2525936
cve.org/CVERecord?id=CVE-2026-82417
bugzilla.redhat.com/show_bug.cgi?id=2525939
cve.org/CVERecord?id=CVE-2026-82562
nvd.nist.gov/vuln/detail/CVE-2026-82562
github.com/ljharb/qs/commit/8859c37470e11b42b547b275e4e9bd0bc8cc5464
github.com/ljharb/qs/security/advisories/GHSA-w7fw-mjwx-w883
github.com/ljharb/qs/security/advisories/GHSA-x5fp-wj9c-mxmx
access.redhat.com/errata/RHSA-2026:63164
access.redhat.com/security/cve/CVE-2026-17033
access.redhat.com/security/cve/CVE-2026-19197
access.redhat.com/security/cve/CVE-2026-21723
access.redhat.com/security/cve/CVE-2026-9765
access.redhat.com/security/cve/CVE-2026-8595
access.redhat.com/security/cve/CVE-2026-33382
access.redhat.com/security/cve/CVE-2026-8609
access.redhat.com/security/cve/CVE-2026-84375
security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_63164.json
bugzilla.redhat.com/show_bug.cgi?id=2499051
cve.org/CVERecord?id=CVE-2026-8595
nvd.nist.gov/vuln/detail/CVE-2026-8595
grafana.com/security/security-advisories/cve-2026-8595
bugzilla.redhat.com/show_bug.cgi?id=2499061
cve.org/CVERecord?id=CVE-2026-8609
nvd.nist.gov/vuln/detail/CVE-2026-8609
grafana.com/security/security-advisories/cve-2026-8609
bugzilla.redhat.com/show_bug.cgi?id=2506730
cve.org/CVERecord?id=CVE-2026-9765
nvd.nist.gov/vuln/detail/CVE-2026-9765
grafana.com/security/security-advisories/cve-2026-9765
bugzilla.redhat.com/show_bug.cgi?id=2521910
cve.org/CVERecord?id=CVE-2026-17033
nvd.nist.gov/vuln/detail/CVE-2026-17033
grafana.com/security/security-advisories/cve-2026-17033
bugzilla.redhat.com/show_bug.cgi?id=2524303
cve.org/CVERecord?id=CVE-2026-19197
nvd.nist.gov/vuln/detail/CVE-2026-19197
grafana.com/security/security-advisories/cve-2026-19197
bugzilla.redhat.com/show_bug.cgi?id=2506342
cve.org/CVERecord?id=CVE-2026-21723
nvd.nist.gov/vuln/detail/CVE-2026-21723
grafana.com/security/security-advisories/cve-2026-21723
bugzilla.redhat.com/show_bug.cgi?id=2499062
cve.org/CVERecord?id=CVE-2026-33382
nvd.nist.gov/vuln/detail/CVE-2026-33382
grafana.com/security/security-advisories/cve-2026-33382
bugzilla.redhat.com/show_bug.cgi?id=2527118
cve.org/CVERecord?id=CVE-2026-84375
nvd.nist.gov/vuln/detail/CVE-2026-84375
github.com/nodeca/js-yaml/commit/3485bc06ff8a0251505f44a00414d90df2466639
github.com/nodeca/js-yaml/commit/6a8e05f9a485188ed730ac81e81ae221352ef480
github.com/nodeca/js-yaml/commit/d90b6612a5a84385bdcb556c44578eac76dc0f6b
github.com/nodeca/js-yaml/pull/797
github.com/nodeca/js-yaml/releases/tag/3.15.2
github.com/nodeca/js-yaml/releases/tag/4.3.2
github.com/nodeca/js-yaml/security/advisories/GHSA-2883-xcg3-v3hh
ubuntu.com/security/CVE-2026-82417
Left out here: the rest of 2 source descriptions. The JSON record has them.