6.3
MEDIUM CVSS 4.0
CVE-2026-8723
qs.stringify crashes on null/undefined entries in comma-format arrays under encodeValuesOnly
Description

### Summary `qs.stringify` throws `TypeError` when called with `arrayFormat: 'comma'` and `encodeValuesOnly: true` on an array containing `null` or `undefined`. The throw is synchronous and not handled by any of qs's null-related options (`skipNulls`, `strictNullHandling`). ### Details In the comma + `encodeValuesOnly` branch, `lib/stringify.js:145` mapped the array through the raw encoder before joining: ```js obj = utils.maybeMap(obj, encoder); ``` `utils.encode` (`lib/utils.js:195`) reads `str.length` with no null guard, so a `null` or `undefined` element throws `TypeError`. `skipNulls` and `strictNullHandling` are both checked in the per-element loop below this line and never get a chance to run. Same class of bug as the filter-array path fixed in 0c180a4. The vulnerable shape of the comma + `encodeValuesOnly` branch was introduced in 4c4b23d ("encode comma values more consistently", PR #463, 2023-01-19), first released in v6.11.1. #### PoC ```js const qs = require('qs'); qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }); // TypeError: Cannot read properties of null (reading 'length') // at encode (lib/utils.js:195:13) // at Object.maybeMap (lib/utils.js:322:37) // at stringify (lib/stringify.js:145:25) ``` #### Fix `lib/stringify.js:145`, applied in 21f80b3 on `main` and released as v6.15.2: ```diff - obj = utils.maybeMap(obj, encoder); + obj = utils.maybeMap(obj, function (v) { + return v == null ? v : encoder(v); + }); ``` `null` and `undefined` now pass through `maybeMap` unchanged and reach the `join(',')` step as-is. For `{ a: [null, 'b'] }` this produces `a=,b`, matching the non-`encodeValuesOnly` comma path (which already joins before encoding and produces `a=%2Cb` for the same input). Single-element `[null]` arrays still collapse via the existing `obj.join(',') || null` and remain subject to `skipNulls` / `strictNullHandling` in the main loop. ### Affected versions `>=6.11.1 <6.15.2` — fixed in v6.15.2. The vulnerable code shape was introduced in 4c4b23d and first shipped in v6.11.1. Earlier versions — including all of 6.7.x, 6.8.x, 6.9.x, 6.10.x, and 6.11.0 — implemented the comma + `encodeValuesOnly` path differently (joining before encoding) and are not affected. Empirically verified across released versions. ### Impact Application code that calls `qs.stringify` with both `arrayFormat: 'comma'` and `encodeValuesOnly: true` (both non-default) on input that may contain a `null` or `undefined` array element will throw synchronously instead of producing a query string. In a typical Node.js HTTP framework (Express, Fastify, Koa, hapi) the sync throw is caught by the framework's error boundary and the affected request returns a 500; the worker process does not exit and subsequent requests are unaffected. The "kills the worker process" framing applies only to call sites outside a request-handler error boundary (background jobs, startup paths, stream pipelines) or to deployments with framework error handling explicitly disabled. The vulnerable input is a `null` or `undefined` entry inside an array; this is reachable from JSON request bodies or from application code constructing arrays from user input, but not from standard HTML form submissions (which produce strings or omitted fields, not literal `null`).

INFO

Published Date :

May 17, 2026, 12:16 a.m.

Last Modified :

Oct. 23, 2026, 11:10 p.m.

Remotely Exploit :

Yes !

Source :

7ffcee3d-2c14-4c3e-b844-86c6a321a158
Affected Products

The following products are affected by CVE-2026-8723 vulnerability. Even if cvefeed.io is aware of the exact versions of the products that are affected, the information is not represented in the table below.

ID Vendor Product Action
1 Qs_project qs
CVSS Scores
The Common Vulnerability Scoring System is a standardized framework for assessing the severity of vulnerabilities in software and systems. We collect and displays CVSS scores from various sources for each CVE.
Score Version Severity Vector Exploitability Score Impact Score Source
CVSS 134c704f-9b21-4f2e-91b3-4a467353bcc0
CVSS 3.1 MEDIUM 7ffcee3d-2c14-4c3e-b844-86c6a321a158
CVSS 4.0 MEDIUM 7ffcee3d-2c14-4c3e-b844-86c6a321a158
CVSS 4.0 MEDIUM 7ffcee3d-2c14-4c3e-b844-86c6a321a158
Solution
Update the qs library to version 6.15.2 or later to fix a TypeError.
  • Update the qs library to the latest version.
  • Ensure input arrays do not contain null or undefined values.
  • Avoid using arrayFormat: 'comma' with encodeValuesOnly: true.
  • Test the application with the updated library.
Public PoC/Exploit Available at Github

CVE-2026-8723 has a 2 public PoC/Exploit available at Github. Go to the Public Exploits tab to see the list.

References to Advisories, Solutions, and Tools

Here, you will find a curated list of external links that provide in-depth information, practical solutions, and valuable tools related to CVE-2026-8723.

URL Resource
https://github.com/ljharb/qs/commit/21f80b33e5c8b3f7eba1034fff0da4a4a37a1d41
https://github.com/ljharb/qs/security/advisories/GHSA-q8mj-m7cp-5q26
https://github.com/ljharb/qs/security/advisories/GHSA-q8mj-m7cp-5q26
CWE - Common Weakness Enumeration

While CVE identifies specific instances of vulnerabilities, CWE categorizes the common flaws or weaknesses that can lead to vulnerabilities. CVE-2026-8723 is associated with the following CWEs:

Common Attack Pattern Enumeration and Classification (CAPEC)

Common Attack Pattern Enumeration and Classification (CAPEC) stores attack patterns, which are descriptions of the common attributes and approaches employed by adversaries to exploit the CVE-2026-8723 weaknesses.

We scan GitHub repositories to detect new proof-of-concept exploits. Following list is a collection of public exploits and proof-of-concepts, which have been published on GitHub (sorted by the most recently updated).

Easydash to create Dashboard

Dockerfile JavaScript HTML TypeScript CSS

Updated: 4 months, 1 week ago
0 stars 0 fork 0 watcher
Born at : April 1, 2026, 7:11 p.m. This repo has been linked 1 different CVEs too.

CVEs assigned by the Harborist CNA.

Updated: 3 months, 1 week ago
3 stars 0 fork 0 watcher
Born at : Nov. 26, 2024, 8:33 p.m. This repo has been linked 12 different CVEs too.

Results are limited to the first 15 repositories due to potential performance issues.

The following list is the news that have been mention CVE-2026-8723 vulnerability anywhere in the article.

The following table lists the changes that have been made to the CVE-2026-8723 vulnerability over time.

Vulnerability history details can be useful for understanding the evolution of a vulnerability, and for identifying the most recent changes that may impact the vulnerability's severity, exploitability, or other characteristics.

  • CVE Translated by [email protected]

    Oct. 23, 2026

    Action Type Old Value New Value
    Added Translation Title: qs de ljharb, Description: ### Resumen `qs.stringify` lanza `TypeError` cuando se llama con `arrayFormat: 'comma'` y `encodeValuesOnly: true` en un array que contiene `null` o `undefined`. El lanzamiento es síncrono y no es manejado por ninguna de las opciones de qs relacionadas con nulos (`skipNulls`, `strictNullHandling`). ### Detalles En la rama de coma + `encodeValuesOnly`, `lib/stringify.js:145` mapeó el array a través del codificador en bruto antes de unir: ```js obj = utils.maybeMap(obj, encoder); ``` `utils.encode` (`lib/utils.js:195`) lee `str.length` sin una protección contra nulos, por lo que un elemento `null` o `undefined` lanza `TypeError`. `skipNulls` y `strictNullHandling` se verifican en el bucle por elemento debajo de esta línea y nunca tienen la oportunidad de ejecutarse. Misma clase de error que la ruta de filtro de array corregida en 0c180a4. La forma vulnerable de la rama de coma + `encodeValuesOnly` se introdujo en 4c4b23d ('encode comma values more consistently', PR #463, 2023-01-19), lanzada por primera vez en v6.11.1. #### PoC ```js const qs = require('qs'); qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }); // TypeError: Cannot read properties of null (reading 'length') // at encode (lib/utils.js:195:13) // at Object.maybeMap (lib/utils.js:322:37) // at stringify (lib/stringify.js:145:25) ``` #### Corrección `lib/stringify.js:145`, aplicado en 21f80b3 en `main` y lanzado como v6.15.2: ```diff - obj = utils.maybeMap(obj, encoder); + obj = utils.maybeMap(obj, function (v) { + return v == null ? v : encoder(v); + }); ``` `null` y `undefined` ahora pasan por `maybeMap` sin cambios y llegan al paso `join(',')` tal cual. Para `{ a: [null, 'b'] }` esto produce `a=,b`, coincidiendo con la ruta de coma sin `encodeValuesOnly` (que ya une antes de codificar y produce `a=%2Cb` para la misma entrada). Los arrays de un solo elemento `[null]` todavía se colapsan a través del `obj.join(',') || null` existente y permanecen sujetos a `skipNulls` / `strictNullHandling` en el bucle principal. ### Versiones afectadas `>=6.11.1 anterior a 6.15.2` — corregido en v6.15.2. La forma de código vulnerable se introdujo en 4c4b23d y se envió por primera vez en v6.11.1. Versiones anteriores — incluyendo todas las 6.7.x, 6.8.x, 6.9.x, 6.10.x y 6.11.0 — implementaron la ruta de coma + `encodeValuesOnly` de manera diferente (uniendo antes de codificar) y no están afectadas. Verificado empíricamente en todas las versiones lanzadas. ### Impacto El código de aplicación que llama a `qs.stringify` con `arrayFormat: 'comma'` y `encodeValuesOnly: true` (ambos no predeterminados) en una entrada que puede contener un elemento de array `null` o `undefined` lanzará de forma síncrona en lugar de producir una cadena de consulta. En un framework HTTP típico de Node.js (Express, Fastify, Koa, hapi), el lanzamiento síncrono es capturado por el límite de error del framework y la solicitud afectada devuelve un 500; el proceso del trabajador no se cierra y las solicitudes posteriores no se ven afectadas. El encuadre de 'mata el proceso del trabajador' se aplica solo a los sitios de llamada fuera de un límite de error del gestor de solicitudes (trabajos en segundo plano, rutas de inicio, tuberías de flujo) o a implementaciones con el manejo de errores del framework explícitamente deshabilitado. La entrada vulnerable es una entrada `null` o `undefined` dentro de un array; esto es alcanzable desde cuerpos de solicitud JSON o desde código de aplicación que construye arrays a partir de la entrada del usuario, pero no desde envíos de formularios HTML estándar (que producen cadenas o campos omitidos, no `null` literal).
  • CVE Modified by 7ffcee3d-2c14-4c3e-b844-86c6a321a158

    Jun. 17, 2026

    Action Type Old Value New Value
    Added Affected [{'repo': 'https://github.com/ljharb/qs', 'vendor': 'ljharb', 'product': 'qs', 'versions': [{'status': 'affected', 'version': '6.11.1', 'lessThan': '6.15.2', 'versionType': 'semver'}], 'packageName': 'qs', 'collectionURL': 'https://npmjs.com/qs', 'defaultStatus': 'unaffected'}]
  • CVE Modified by 134c704f-9b21-4f2e-91b3-4a467353bcc0

    Jun. 17, 2026

    Action Type Old Value New Value
    Added SSVC {'id': 'CVE-2026-8723', 'role': 'CISA Coordinator', 'options': [{'exploitation': 'poc'}, {'automatable': 'yes'}, {'technicalImpact': 'partial'}], 'version': '2.0.3', 'timestamp': '2026-05-18T14:02:12.499337Z'}
  • CVE Modified by 134c704f-9b21-4f2e-91b3-4a467353bcc0

    May. 18, 2026

    Action Type Old Value New Value
    Added Reference https://github.com/ljharb/qs/security/advisories/GHSA-q8mj-m7cp-5q26
  • New CVE Received by 7ffcee3d-2c14-4c3e-b844-86c6a321a158

    May. 17, 2026

    Action Type Old Value New Value
    Added Description ### Summary `qs.stringify` throws `TypeError` when called with `arrayFormat: 'comma'` and `encodeValuesOnly: true` on an array containing `null` or `undefined`. The throw is synchronous and not handled by any of qs's null-related options (`skipNulls`, `strictNullHandling`). ### Details In the comma + `encodeValuesOnly` branch, `lib/stringify.js:145` mapped the array through the raw encoder before joining: ```js obj = utils.maybeMap(obj, encoder); ``` `utils.encode` (`lib/utils.js:195`) reads `str.length` with no null guard, so a `null` or `undefined` element throws `TypeError`. `skipNulls` and `strictNullHandling` are both checked in the per-element loop below this line and never get a chance to run. Same class of bug as the filter-array path fixed in 0c180a4. The vulnerable shape of the comma + `encodeValuesOnly` branch was introduced in 4c4b23d ("encode comma values more consistently", PR #463, 2023-01-19), first released in v6.11.1. #### PoC ```js const qs = require('qs'); qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }); // TypeError: Cannot read properties of null (reading 'length') // at encode (lib/utils.js:195:13) // at Object.maybeMap (lib/utils.js:322:37) // at stringify (lib/stringify.js:145:25) ``` #### Fix `lib/stringify.js:145`, applied in 21f80b3 on `main` and released as v6.15.2: ```diff - obj = utils.maybeMap(obj, encoder); + obj = utils.maybeMap(obj, function (v) { + return v == null ? v : encoder(v); + }); ``` `null` and `undefined` now pass through `maybeMap` unchanged and reach the `join(',')` step as-is. For `{ a: [null, 'b'] }` this produces `a=,b`, matching the non-`encodeValuesOnly` comma path (which already joins before encoding and produces `a=%2Cb` for the same input). Single-element `[null]` arrays still collapse via the existing `obj.join(',') || null` and remain subject to `skipNulls` / `strictNullHandling` in the main loop. ### Affected versions `>=6.11.1 <6.15.2` — fixed in v6.15.2. The vulnerable code shape was introduced in 4c4b23d and first shipped in v6.11.1. Earlier versions — including all of 6.7.x, 6.8.x, 6.9.x, 6.10.x, and 6.11.0 — implemented the comma + `encodeValuesOnly` path differently (joining before encoding) and are not affected. Empirically verified across released versions. ### Impact Application code that calls `qs.stringify` with both `arrayFormat: 'comma'` and `encodeValuesOnly: true` (both non-default) on input that may contain a `null` or `undefined` array element will throw synchronously instead of producing a query string. In a typical Node.js HTTP framework (Express, Fastify, Koa, hapi) the sync throw is caught by the framework's error boundary and the affected request returns a 500; the worker process does not exit and subsequent requests are unaffected. The "kills the worker process" framing applies only to call sites outside a request-handler error boundary (background jobs, startup paths, stream pipelines) or to deployments with framework error handling explicitly disabled. The vulnerable input is a `null` or `undefined` entry inside an array; this is reachable from JSON request bodies or from application code constructing arrays from user input, but not from standard HTML form submissions (which produce strings or omitted fields, not literal `null`).
    Added CVSS V4.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
    Added CVSS V3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
    Added CWE CWE-476
    Added Reference https://github.com/ljharb/qs/commit/21f80b33e5c8b3f7eba1034fff0da4a4a37a1d41
    Added Reference https://github.com/ljharb/qs/security/advisories/GHSA-q8mj-m7cp-5q26
EPSS is a daily estimate of the probability of exploitation activity being observed over the next 30 days. Following chart shows the EPSS score history of the vulnerability.