Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1359 CNY

100%

CVE-2026-110910— qs.stringify with allowEmptyArrays does not encode the keys of empty arrays, allowing query string parameter injection

Quick assessment

Affected
ljharb qs
Exploitation
No confirmed in-the-wild exploitation; assess based on exposure
Recommended action
Check the vendor advisory and references for a fixed version. If immediate upgrade is impossible, restrict exposure and increase monitoring.

摘要 当 启用 选项时,空数组的键名不会被编码,尽管默认情况下所有键名都会经过编码。如果键名中包含 (或配置的 )、 或 字符,这些字符会被解析为查询字符串语法的一部分,而非数据内容。因此,调用方提供的键名可以注入额外的参数到序列化的查询字符串中,或者提前截断查询字符串。 详细说明 在 文件中, 分支会提前返回 ,从而跳过了对所有其他键名执行 (编码器)和 (格式化器)的代码逻辑。因此: 被序列化为 (键名被正确编码)。 却被序列化为 (键名未被编码)。 这种提前返回机制适用于任意嵌套深度(例如 会生成 )、所有

CVSS 3.7 · Low
Get alerts for future matching vulnerabilities Log in to subscribe

I. Basic Information for CVE-2026-110910

Vulnerability Information

Have questions about the vulnerability? See if Shenlong's analysis helps!
View Shenlong Deep Dive ↗

Although we use advanced large model technology, its output may still contain inaccurate or outdated information.Shenlong tries to ensure data accuracy, but please verify and judge based on the actual situation.

Vulnerability Title
qs.stringify with allowEmptyArrays does not encode the keys of empty arrays, allowing query string parameter injection
Source: CVE Program / CVE List V5
Vulnerability Description
### Summary `qs.stringify` with `allowEmptyArrays: true` writes the key of an empty array without encoding it, even though keys are encoded by default. A key that contains `&` (or the configured `delimiter`), `=`, or `#` ∴ becomes query string syntax instead of data, so a caller-supplied key name can add parameters to the serialized query string, or cut it short. ### Details In `lib/stringify.js`, the `allowEmptyArrays` branch returns `adjustedPrefix + '[]'` early, before the code that passes every other key through `encoder` and `formatter`. So `{ "x&k=v": ["1"] }` serializes as `x%26k%3Dv%5B0%5D=1`, but `{ "x&k=v": [] }` serializes as `x&k=v[]`. The early return applies at any depth (`{ "a": { "b&k=v": [] } }` gives `a[b&k=v][]`), under every `arrayFormat`, with `allowDots`, and with a custom `encoder`, which is never called for that key. With `encode: false` or `encodeValuesOnly: true`, keys are intentionally left unencoded on every path; those configurations are not affected. #### PoC ```js var qs = require("qs"); var query = qs.stringify({ q: "hi", "x&apiKey=evil&y": [] }, { allowEmptyArrays: true }); // "q=hi&x&apiKey=evil&y[]" qs.parse(query); // { q: "hi", x: "", apiKey: "evil", y: [""] } qs.stringify({ "x#": [], z: "1" }, { allowEmptyArrays: true }); // "x#[]&z=1": in a URL, everything after "#" becomes the fragment ``` #### Fix Applied in 234d505 on `main` and released as v6.17.0: the key of an empty array goes through `encoder` and `formatter` exactly as the key of any other value does, so `{ "x&apiKey=evil&y": [] }` now serializes as `x%26apiKey%3Devil%26y[]`. Keys that need no encoding serialize as before, with two exceptions that match every other path: the brackets of a nested key are now encoded (`a[b][]` becomes `a%5Bb%5D[]`, which `qs.parse` reads identically), and with `encodeDotInKeys`, a dot in the key becomes `%252E` instead of `%2E` (which `decodeDotInKeys` previously misread as nesting). ### Affected versions `>=6.12.0 <6.17.0`, fixed in v6.17.0. `allowEmptyArrays` was introduced in f22b2bc and first shipped in v6.12.0, with this early return. Every release from v6.12.0 through v6.16.1 is affected. Earlier versions have no `allowEmptyArrays` option and are not affected. ### Impact An application that passes an object whose key names come from untrusted input to `qs.stringify` with `allowEmptyArrays: true` (for example, to forward a parsed JSON body or user-selected fields to an upstream service) can have parameters injected into the resulting query string. The injected parameters are not keys of the object, so deleting or overwriting a key on the object (such as setting a trusted `apiKey` after copying the user's fields) does not remove them; whether the attacker's value or the application's wins depends on how the receiving side handles a duplicate parameter. A `#` in such a key ends the query string early when the result is placed in a URL. `allowEmptyArrays` is off by default, and only keys whose value (after any `filter`) is an empty array are affected.
Source: CVE Program / CVE List V5
CVSS Information
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
Source: CVE Program / CVE List V5
Vulnerability Type
对输出编码和转义不恰当
Source: CVE Program / CVE List V5

Affected Products

Vendor Product Affected Versions CPE Subscribe
ljharb qs 6.12.0 ~ 6.17.0 -

II. Public POCs for CVE-2026-110910

# POC Description Source Link Shenlong Link
AI-Generated POC Premium

No public POC found.

Login to generate AI POC

III. Intelligence Information for CVE-2026-110910

请登录查看更多情报信息。

Other References for CVE-2026-110910 (4)

IV. Related Vulnerabilities