Impact
The vulnerability arises when qs.stringify calls utils.isBuffer on an object that contains a constructor property with a non-function isBuffer member. With a value like { constructor: { isBuffer: "x" } }, the call throws a TypeError, causing the serialize operation to fail. The exception propagates up the stack and, in most Node.js web frameworks, results in a 500 response or, if not caught in an async context, an unhandled promise rejection that can terminate the process. The weakness reflects improper validation of a function pointer (CWE‑248) and misuse of an unsafe function call (CWE‑703).
Affected Systems
The issue affects the npm package qs from the ljharb project. All releases from version 2.2.5 up to, but excluding, 6.16.0 contain the vulnerable code. Express 4, its default query parser, and body-parser with extended: true use qs.parse with allowPrototypes: true or plainObjects: true, allowing attacker-supplied objects to reach qs.stringify. The fix was committed in e83d321 and released in qs 6.16.0, which added a typeof check before invoking constructor.isBuffer.
Risk and Exploitability
The CVSS score is 6.3, indicating a moderate severity vulnerability. EPSS is not available, and the issue is not listed in the CISA KEV catalog. An attacker can trigger the TypeError by sending a crafted query string, JSON body, or by abusing parse options, meaning any unauthenticated client can provoke a synchronous exception or, if the exception is not properly handled, cause the process to exit. In a typical Node.js web framework, the impact is limited to a single request returning 500, but it can degrade to a full denial of service in applications that do not guard against unhandled promise rejections.
OpenCVE Enrichment