Skip to content
RESEARCH INDEX BREACHROAD / INTELLIGENCE NOTE

qs 6.16.0: two denial-of-service flaws in a widely used Node.js parser

CVE-2026-82417 and CVE-2026-82562 show how a hostile object shape and commas under a[] can violate parser assumptions, causing exceptions or memory pressure.

PUBLIC RESEARCH
AUTHOR
/ CEO Breachroad · OSCP · PNPT
PUBLISHED
30 August 2026
READING TIME
18 min read
TOPIC
Supply Chain Security
qs 6.16.0: two denial-of-service flaws in a widely used Node.js parser

Two new records affecting the qs package entered NVD on 30 August in Warsaw time. CVE-2026-82417 can trigger an exception when an application re-serialises client-controlled data. CVE-2026-82562 bypasses the configured array limit for one combination of bracket and comma syntax. Both defects are fixed in qs 6.16.0.

Neither issue provides code execution or database access. Their primary effect is availability loss: an HTTP 500 response, termination of a worker process or memory consumption proportional to the input size. They still deserve attention because of where qs sits in the ecosystem. It converts complex query strings and application/x-www-form-urlencoded bodies into JavaScript objects. It may run inside a framework, API gateway or adapter even when the application team never imports it directly.

Today’s development is the publication of unambiguous CVE records and their arrival in vulnerability-management feeds. The project advisories are dated 29 August, while NVD registered the records after midnight on 30 August in Warsaw. That distinction does not change remediation priority, but it keeps the timeline accurate.

CVE-2026-82417: a hostile object shape mistaken for a buffer interface

The first defect sits at the boundary between parse() and stringify(). When serialising a value, qs.stringify() checks whether an object is a buffer. The affected implementation read obj.constructor.isBuffer, tested only whether the property was truthy and then invoked it as a function.

The problem is that constructor and isBuffer can be ordinary data keys. If input produces an object whose isBuffer value is a string or another non-callable value, the check ends in a TypeError. No genuine Buffer object or prototype mutation is required. The dangerous ingredient is simply a data shape that retains an own constructor.isBuffer property.

The default qs.parse() configuration drops a constructor key, but plainObjects: true or allowPrototypes: true can preserve it. The advisory also notes that Express 4 and body-parser use allowPrototypes: true in some common parsing paths. This does not make every Express application vulnerable. A reachable flow must subsequently pass the object into qs.stringify()—for example while constructing a redirect, an upstream request, a cache key or a normalised URL.

The result depends on error handling. A framework boundary may turn the exception into a failed request. An unguarded asynchronous continuation or background job may let it terminate a worker. The record carries CVSS 4.0: 6.3 and CVSS 3.1: 5.3; the stated impact is availability, not confidentiality or integrity.

The affected range is unusually broad: qs 2.2.5 through 6.15.3, with the fix in 6.16.0. The patch verifies that constructor.isBuffer is actually a function before calling it. This small change illustrates a larger rule: duck typing over untrusted data is a security decision, not merely a programming convenience.

CVE-2026-82562: the limit worked for one spelling but not for a[]

The second flaw requires comma: true together with throwOnLimitExceeded: true. The first option splits comma-separated values into arrays. The second is intended to stop parsing once arrayLimit is exceeded. The control worked for a flat key, but the semantically similar a[]=... form followed another branch.

The parser split the value on commas and then wrapped the result as one element in an outer array. The length check saw a wrapper of length one instead of the inner array. A client could therefore place many elements inside a single a[] parameter even though the application explicitly requested hard rejection beyond its limit.

The prerequisites matter. comma and throwOnLimitExceeded are not jointly enabled by default. The resource cost also grows linearly with attacker-supplied bytes. Node.js’s default request-line limit constrains very large query strings, but the vulnerable parser may receive a form body if upstream layers permit larger requests.

CVE-2026-82562 affects 6.14.2 through 6.15.3 and is also fixed in 6.16.0. NVD reports CVSS 4.0: 6.3 and CVSS 3.1: 3.7. The control fails relative to the application’s intended resource policy, but the issue is not an infinitely expanding payload: the effective maximum request size still bounds the work.

This flaw follows earlier remediation for CVE-2026-2391. Version 6.14.2 introduced checking for comma-separated values but missed the precise []= variant. That history is a valuable AppSec lesson: regression tests must cover semantically equivalent encodings, not only the one example in the original report.

Establishing actual reachability

Finding qs in a lockfile is not enough to quantify risk. First identify the version included in each production artefact. A monorepo may contain several copies, and a transitive declaration can resolve differently depending on the package manager, overrides and lockfile used for a specific build. Inspect the deployed image or package SBOM, dependency tree and build lockfile.

For CVE-2026-82417, map parse → transform → stringify flows. Pay particular attention to application-level reverse proxies, gateways that rewrite parameters, redirect generators, HTTP clients constructing upstream URLs and asynchronous jobs serialising request data. Then determine whether parsing preserves prototype-related keys or creates prototype-free objects.

For CVE-2026-82562, search for comma: true and throwOnLimitExceeded: true. Determine whether the parser receives a query string, a form body or an object already transformed by another component. Record header and body limits at the CDN, load balancer, ingress, framework and route. The smallest effective limit defines the real resource ceiling.

Do not expect SCA alone to establish reachability. SCA can tell you that an affected version exists. Call-path and configuration analysis determine whether hostile data reaches the vulnerable branch.

Upgrade and layered controls

The preferred fix is qs 6.16.0 or a later release accepted by the application owner. Because qs is frequently transitive, this may require a framework upgrade or a controlled dependency override. An override still needs compatibility tests covering query strings, forms, repeated keys, arrays, nested objects, commas and limit errors.

If immediate upgrading is impossible, disable comma: true where it is not required and avoid re-serialising unfiltered client structures. Do not enable allowPrototypes without a documented need. At the HTTP boundary, enforce query-string and body-size caps, timeouts and concurrency limits. These measures reduce the impact of CVE-2026-82562 but do not replace the CVE-2026-82417 patch.

Handle errors inside the asynchronous boundary where they can arise. Orchestrator restarts improve recovery but do not remove the weakness; without rate controls, a remote party may repeatedly trigger worker failure.

Detection and safe validation

Look for a sudden increase in TypeError events referencing isBuffer or qs/lib/utils, repeated 500 responses from routes that rewrite parameters and worker restarts correlated with similar input shapes. For the second flaw, monitor unusually long comma-separated values, [] keys, heap pressure, longer garbage-collection pauses and rejections from upstream body-size controls.

Validate the patch in a test environment with small, harmless cases that exceed a deliberately low limit. Memory exhaustion is unnecessary. A useful regression proves that 6.16.0 produces a controlled RangeError for every relevant key form and never invokes a non-callable isBuffer value.

Source facts and Breachroad conclusions

Affected versions, mechanisms, scores and the fixed release come from the project advisories and NVD records. The inventory method, telemetry and action ordering are Breachroad defensive conclusions. The primary sources do not report confirmed exploitation in the wild. An affected package version is exposure evidence, not proof of compromise.

Primary sources

These defects are easiest to understand where application code, frameworks and infrastructure meet. Our cybersecurity training helps teams recognise data boundaries and design useful security regressions. Organisations needing reachability evidence can include parsers, gateways and APIs in a controlled web and API penetration test.

SHARE / COPY