Skip to main content

qs CVE-2026-82417

| EUVDEUVD-2026-68140 MEDIUM
Uncaught Exception (CWE-248)
2026-08-30 7ffcee3d-2c14-4c3e-b844-86c6a321a158 GHSA-4mjr-xmp4-gh2g
6.3
CVSS 4.0 · Vendor: 7ffcee3d-2c14-4c3e-b844-86c6a321a158
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Send crafted HTTP request with constructor.isBuffer payload
  2. Delivery
    Express/body-parser parses with allowPrototypes, preserving constructor key
  3. Exploit
    req.body carries malicious shape
  4. Install
    Application calls qs.stringify on req.body
  5. C2
    utils.isBuffer invokes non-callable property
  6. Execute
    TypeError thrown uncaught
  7. Impact
    HTTP 500 (sync) or process crash (async handler)

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A10:2025 - Mishandling of Exceptional Conditions
ASVS 5.0
V16 - Security Logging and Error Handling Exception handling completeness
Exploitation Conditions

Two conditions must both be satisfied. First, attacker-controlled data must reach a parsed object that retains the constructor key as an own property: this occurs when qs.parse is called with plainObjects: true or allowPrototypes: true (Express 4 default query-parser and body-parser with extended: true satisfy this with no non-default application configuration), or when a matching shape is introduced via JSON.parse from an attacker-supplied JSON body (no qs option involved). Default qs.parse options silently drop the constructor key and are not affected. Second, that parsed object must subsequently be passed to qs.stringify - typically in a code path that reconstructs a query string for a redirect or upstream HTTP call. Impact severity depends on calling context: inside a synchronous Express error boundary the process survives and returns HTTP 500; inside an async handler or background job the throw becomes an unhandled rejection and may terminate the process.

Impact

The CVSS 4.0 score of 6.3 (AV:N/AC:L/AT:P/PR:N/UI:N/VA:L) accurately reflects moderate real-world risk bounded by a critical application-level precondition: the target application must re-serialize attacker-influenced data with qs.stringify. AT:P (Attack Requirements: Present) captures this prerequisite. However, the named triggering stacks - Express 4 with default settings and body-parser with extended: true - are among the most common Node.js HTTP configurations in production, meaningfully widening the realistic attack surface beyond what AT:P alone suggests. No EPSS score was provided, so exploitation probability cannot be quantified from available data. POC is confirmed (embedded in the advisory), and exploitation is trivial once conditions are met. Active exploitation via CISA KEV is not confirmed. Impact is bounded: in most Express error boundaries the throw produces a 500 and the process survives; in async handlers or background jobs, an unhandled rejection can terminate the process, making worst-case impact a service outage. No confidentiality or integrity exposure exists - the 'Information Disclosure' tag in the source intelligence is incorrect and directly contradicted by the CVSS vector (VC:N/VI:N).

Exploit ScenarioDerived

An attacker sends a POST request to an Express 4 application using body-parser with extended: true, with a JSON body such as {"a":{"constructor":{"isBuffer":"x"}}}. The framework parses this with allowPrototypes: true, placing the malicious shape in req.body. When the handler calls qs.stringify(req.body) to rebuild a query string for an upstream redirect, utils.isBuffer attempts to invoke the string "x" as a function, throwing a TypeError. In an async handler this becomes an unhandled promise rejection, crashing the Node.js process. A working PoC demonstrating this is included in the CVE description.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.3% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAI

The qs.stringify function in the qs Node.js query-string library throws an uncaught TypeError when serializing any object whose constructor.isBuffer property is truthy but not callable, enabling denial of service against applications that re-serialize attacker-controlled data. Express 4 (default query-parser) and body-parser with extended: true both parse incoming HTTP data using options that preserve the constructor key in output, meaning a crafted request body or query string can reach the vulnerable code path with no non-default configuration required on the target application. A working proof-of-concept is embedded in the CVE description; no CISA KEV listing exists at time of analysis.

RemediationAI

Upgrade the qs package to v6.16.0 or later, which adds a typeof obj.constructor.isBuffer === 'function' guard before the call, eliminating the throw without changing serialization behavior for real Buffer, safer-buffer, or browserify buffer instances (confirmed by commit e83d321: https://github.com/ljharb/qs/commit/e83d321ffafb38cf210683ac31714fce6ce1c6c6). If an immediate upgrade is blocked, the primary compensating control is to audit every application code path that calls qs.stringify on data originating from qs.parse with plainObjects: true or allowPrototypes: true, and either switch to default parse options (which drop the constructor key, preventing the dangerous shape from forming) or insert schema/shape validation before the stringify call. Switching away from allowPrototypes: true may break callers that depend on prototype-chain properties being preserved - test for regressions before deploying. For Express 4 applications, the specific risk surface is any route handler that rebuilds req.query or req.body into a query string via qs.stringify for redirects or upstream requests.

Affected VersionsENISA

qs 2.2.5 <6.16.0

Affected Packages

npm qs fix: 6.16.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in npm

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The qs library's utils.isBuffer function (lib/utils.js:332) duck-types Node.js Buffer instances by first checking that obj.constructor.isBuffer is truthy, then immediately invoking it as a function - without ever verifying via typeof that it actually is one. Any object carrying a non-callable truthy value at constructor.isBuffer (a string, number, plain object, or array) reaches the uncaught call and throws. qs.stringify (lib/stringify.js:127) invokes utils.isBuffer on every non-primitive value it serializes, so the crash is reachable from the public API. CWE-248 (Uncaught Exception) precisely describes the root cause: a synchronous throw in a code path with no local catch. The vulnerable property names (constructor, isBuffer) are ordinary own-property names, not prototype chain access, so the flaw is reachable whenever qs.parse is called with plainObjects: true or allowPrototypes: true, or when a matching shape arrives via JSON.parse. The affected scope is cpe:2.3:a:ljharb:qs:*:*:*:*:*:node.js:*:* for versions >=2.2.5 through <=6.15.3.

Know when Node.js gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (7ffcee3d-2c14-4c3e-b844-86c6a321a158) PRIMARY 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
vuln.today AI 3.7 LOW

Application must re-serialize attacker-parsed data (AC:H); network-reachable via HTTP with no authentication (AV:N/PR:N); availability impact only (A:L), no confidentiality or integrity effect.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
SUSE 5.3 MEDIUM
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Red Hat 7.5 HIGH

Primary rating from Vendor (7ffcee3d-2c14-4c3e-b844-86c6a321a158).

CVSS VectorVendor: 7ffcee3d-2c14-4c3e-b844-86c6a321a158

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
Present
Privileges Required
None
User Interaction
None
Vulnerable system: Confidentiality
None
Vulnerable system: Integrity
None
Vulnerable system: Availability
Low
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

DescriptionCVE.org

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.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 927 npm packages depend on qs (16 direct, 911 indirect)

Ecosystem-wide dependent count for version 2.2.5.

Threat Intelligence Overview

EPSS Score
0.3%
Top 82% exploitable
Prevalence
Ubiquitous
one of the most downloaded npm packages, bundled with Express ecosystem
Threat Intel
1
1 sources
Exploit
POC
Public exploit code exists
Data Quality
8 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA MSRC Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC Yes
EPSS 0.3%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Out-of-Cycle
Exploitation
Poc
System Exposure· derived
Open
Automatable
Yes
Human Impact· derived
High
Technical Impact
Partial

Priority Score

52
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +32
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.

CVE-2025-68613 HIGH POC
8.8 Dec 19

Remote code execution in n8n's workflow expression evaluation system allows an authenticated user with workflow creation

CVE-2024-41713 CRITICAL POC
9.1 Oct 21

A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2023-44487 HIGH POC
7.5 Oct 10

Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2024-35286 CRITICAL POC
9.8 Oct 21

A vulnerability in NuPoint Messenger (NPM) of Mitel MiCollab through 9.8.0.33 allows an unauthenticated attacker to cond

Vendor StatusVendor

Debian

node-qs
Release Status Fixed Version Urgency
bullseye vulnerable 6.9.4+ds-1+deb11u1 -
bookworm vulnerable 6.11.0+ds+~6.9.7-3 -
trixie vulnerable 6.13.0+ds+~6.9.16-1 -
forky, sid vulnerable 6.15.2+ds+~6.15.1-1 -
(unstable) fixed (unfixed) -

SUSE

Severity: Moderate
Product Status
SUSE Linux Enterprise Desktop 15 SP7 Affected
SUSE Linux Enterprise High Performance Computing 12 Not-Affected
SUSE Linux Enterprise Micro 5.3 Not-Affected
SUSE Linux Enterprise Micro 5.3 Not-Affected
SUSE Linux Enterprise Micro 5.4 Not-Affected

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy