CVE-2026-110910 json
qs.stringify with allowEmptyArrays does not encode the keys of empty arrays, allowing query string parameter injection
published 13d ago modified 5d ago also EUVD-2026-110630
- cvss
- 3.7
- version 3.1, CNA
- cisa kev
- Not listed
- not in CISA's catalog
- epss
- 0.3%
- EPSS 0.3% chance of exploitation in 30 days, percentile 21%
- public exploits
- 0
- none known
Summary
### 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 `#` therefore 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, and backported to v6.16.2, v6.15.4, v6.14.3, v6.13.4, and v6.12.6: 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.12.6`, fixed in v6.12.6
- `>=6.13.0 <6.13.4`, fixed in v6.13.4
- `>=6.14.0 <6.14.3`, fixed in v6.14.3
- `>=6.15.0 <6.15.4`, fixed in v6.15.4
- `>=6.16.0 <6.16.2`, fixed in v6.16.2
v6.17.0 and later are not affected.
`allowEmptyArrays` was introduced in f22b2bc and first shipped in v6.12.0, with this early return. 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.
Patch / fix
- ljharb qs 6.12.6, 6.13.4, 6.14.3, 6.15.4, 6.16.2
- git-bug openSUSE Tumbleweed 0.11.0-4.1
opensuse advisories openSUSE-SU-2026:12429-1
- github.com/ljharb/qs@234d505 commit
- github.com/ljharb/qs@6b8bf1a commit
- github.com/ljharb/qs@033526f commit
- github.com/ljharb/qs@f9dd483 commit
- github.com/ljharb/qs@ad445aa commit
- github.com/ljharb/qs@5d3b1b9 commit
- github.com/ljharb/qs#561 pull request
Is CVE-2026-110910 in your stack? Fencer shows which of your repositories are affected as soon as an advisory lands, and opens the fix as a pull request.
Check with FencerVendor advisories
What the vendors themselves say about their products: affected, fixed or not affected, and what to do.
red hat product security vex CVE-2026-110910 updated cvss 3.7
qs: qs: Query parameter injection via unencoded empty array keys
-
Red Hat Ansible Automation Orchestrator 2026 ansible-automation-platform/automation-orchestrator-ui-rhel9 Red Hat Cost Management On Premise costmanagement/costmanagement-ui-rhel10 Red Hat Cryostat 4 cryostat/cryostat-openshift-console-plugin-rhel9 Red Hat Migration Toolkit for Applications 8 mta/mta-ui-rhel9, mta/mta-solution-server-rhel9 Red Hat Migration Toolkit for Containers rhmtc/openshift-migration-ui-rhel8 Red Hat Multicluster Engine for Kubernetes multicluster-engine/console-mce-rhel9affected: workaround, no fix available “Fix deferred”
+29 more productsfewer
Red Hat Node HealthCheck Operator workload-availability/node-healthcheck-rhel9-operator, workload-availability/node-healthcheck-operator-bundle, workload-availability/node-healthcheck-must-gather-rhel9 Red Hat OpenShift Lightspeed openshift-lightspeed/lightspeed-console-plugin-rhel9, openshift-lightspeed/lightspeed-agentic-console-rhel9, openshift-lightspeed/lightspeed-console-plugin-419-rhel9, openshift-lightspeed/lightspeed-console-plugin-pf5-rhel9 Red Hat OpenShift Pipelines openshift-pipelines/pipelines-hub-ui-rhel8, openshift-pipelines/pipelines-hub-ui-rhel9, openshift-pipelines/pipelines-console-plugin-rhel8, openshift-pipelines/pipelines-console-plugin-rhel9, openshift-pipelines/pipelines-console-plugin-pf5-rhel9 Red Hat OpenShift Serverless openshift-serverless-1/logic-rhel9-operator, openshift-serverless-1/kn-eventing-integrations-transform-jsonata-rhel9 Red Hat OpenShift Service Mesh 3 openshift-service-mesh/kiali-rhel9-operator, openshift-service-mesh/kiali-operator-bundle Red Hat Advanced Cluster Management for Kubernetes 2 rhacm2/console-rhel9 Red Hat Advanced Cluster Security 4 advanced-cluster-security/rhacs-main-rhel8, advanced-cluster-security/rhacs-main-rhel9 Red Hat Ansible Automation Platform 2 automation-gateway, ansible-automation-platform-27/mcp-server-rhel9, ansible-automation-platform-tech-preview/mcp-server-rhel9 Red Hat build of Apache Camel - HawtIO 4 rhaf-hawtio-maven-repository.zip Red Hat build of Apache Camel for Spring Boot 4 rhaf-camel-maven-repository.zip, rhaf-camel-spring-boot-maven-repository.zip, rhaf-camel-for-springboot-maven-repository.zip Red Hat Build of Podman Desktop rh-podman-desktop Red Hat Connectivity Link 1 rhcl-1/rhcl-rhdh-dynamic-plugin-rhel9 Red Hat Data Grid 8 redhat-datagrid-maven-repository.zip Red Hat Developer Hub 1 rhdh/rhdh-hub-rhel9, rhdh/red-hat-developer-hub-backstage-plugin-lightspeed, rhdh/red-hat-developer-hub-backstage-plugin-orchestrator, rhdh/red-hat-developer-hub-backstage-plugin-lightspeed-backend, rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend, rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets, +2 more Red Hat Discovery 2 discovery/discovery-ui-rhel9 Red Hat Enterprise Linux 9 pcs, sgx-mpa, tdx-qgs, pcs-snmp, sgx-libs, sgx-pccs, +4 more Red Hat Enterprise Linux 10 pcs, grafana, linux-sgx, grafana-pcp Red Hat Enterprise Linux AI (RHEL AI) 3 rhelai3/bootc-cuda-rhel9, rhelai3/bootc-rocm-rhel9, rhelai3/bootc-gaudi-rhel9, rhelai3/disk-image-cuda-rhel9 Red Hat OpenShift AI (RHOAI) rhoai/odh-core-bff-rhel9, rhoai/odh-dashboard-rhel9, rhoai/odh-mod-arch-maas-rhel9, rhoai/odh-feature-server-rhel9, rhoai/odh-mod-arch-automl-rhel9, rhoai/odh-mod-arch-gen-ai-rhel9, +7 more Red Hat OpenShift Container Platform 4 openshift4/ose-console-rhel9, openshift4/ose-monitoring-plugin-rhel9, openshift4/ose-agent-installer-ui-rhel9 Red Hat OpenShift Container Platform 5 openshift5/ose-monitoring-plugin-rhel9, openshift5/ose-agent-installer-ui-rhel9 Red Hat Openshift Data Foundation 4 odf4/mcg-core-rhel9 Red Hat OpenShift Dev Spaces devspaces/code-rhel9, devspaces/openvsx-rhel9, devspaces/dashboard-rhel9, devspaces/jetbrains-ide-rhel9, devspaces/pluginregistry-rhel9 Red Hat OpenShift GitOps openshift-gitops-1/argocd-rhel9 Red Hat Quay 3 quay/quay-rhel8, quay/quay-rhel9 Red Hat Satellite 6 satellite/iop-remediations-rhel9 Red Hat Trusted Profile Analyzer rhtpa/rhtpa-rhel10, rhtpa/rhtpa-trustification-service-rhel9 Red Hat Secrets Management Console for Red Hat OpenShift external-secrets-management/console-plugin-rhel9 Red Hat Self-service automation portal 2 ansible-automation-platform/automation-portal, ansible-automation-platform/bootc-automation-portal-rhel9 -
Red Hat Hardened Images grafana13.2 13.2.4-0.6.hum1fixed: vendor fix RHSA-2026:94794
-
Red Hat Node HealthCheck Operator workload-availability/node-remediation-console-rhel8 Red Hat 3scale API Management Platform 2 3scale-amp2/system-rhel8 Red Hat Advanced Cluster Management for Kubernetes 2 rhacm2/volsync-rhel9, rhacm2/volsync-operator-bundle Red Hat AMQ Broker 7 amq-broker-bin.zip, amq-broker-maven-repository.zipnot affected: vulnerable code not present
11 more not affected in the full advisory
Red Hat CSAF VEX © Red Hat, Inc., from https://security.access.redhat.com/data/csaf/v2/vex/; changed: reduced to product statuses and remediations. CC BY 4.0 · csaf
CISA SSVC
- Exploitation
- none
- Automatable
- no
- Technical impact
- partial
- Assessed
- 5d ago
Exploit prediction
0.29% chance of exploitation in the next 30 days, higher than 21% of all scored CVEs (FIRST EPSS, 2026-11-09).
CVSS scores
| assigned by | version | score | vector |
|---|---|---|---|
| CNA | 3.1 | 3.7 | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N |
| CNA | 4.0 | 6.3 | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N |
| CNA | 4.0 | 6.3 | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/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 |
Affected products
- ljharb qs
Classification
- Weakness
-
- CWE-116 Improper Encoding or Escaping of Output
References
-
github.com
/ljharb/qs/commit/234d5051f5071efaa025a7ca9e4d34a56a460a1b
patch
-
github.com
/ljharb/qs/commit/6b8bf1a53d7b0c5e7e434eaae8e2c0cffd5c2492
patch
-
github.com
/ljharb/qs/commit/033526fc82f2e80a3d896df2bce9137e34cb5dc5
patch
-
github.com
/ljharb/qs/commit/f9dd4830cb922363822cdfdca2cceb3ed9792224
patch
-
github.com
/ljharb/qs/commit/ad445aa23e4c3a97394c3b9a5f9d7a7159eb1f17
patch
-
github.com
/ljharb/qs/commit/5d3b1b9ec6afd0cfc760c8e12862873789a32fc8
patch
-
github.com
/ljharb/qs/pull/561
patch
-
github.com
/ljharb/qs/security/advisories/GHSA-w4cr-vjpx-p82q
vendor-advisory
-
github.com
/ljharb/qs/issues/626
issue-tracking
Sources
- CVE List CVE-2026-110910
- NVD CVE-2026-110910
Fencer Intel keeps one entry per vulnerability: the CVE id wins, then GHSA, and records that alias each other are merged, except that two CVEs always keep separate entries. The same data is available as JSON.