Cloudanix VulnDB

CVE-2026-2391

Low · 3.7

CVSS

3.7

EPSS

0.5%

Published

Feb 12, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A specially crafted web request can make some Node.js applications run out of memory and become unavailable.

Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Denial Of Service
Component
Library
Class
Denial of service
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

The flaw is a denial-of-service condition in the Node.js `qs` query-string parser when applications enable the non-default `comma: true` option. In that mode, comma-separated parameter values are split into arrays before `arrayLimit` and `throwOnLimitExceeded` checks are applied. As a result, a single query parameter containing a very large number of commas can cause `qs.parse()` to allocate an extremely large array, consuming process memory and potentially crashing the Node.js runtime or the hosting service.

Why it matters to the business

Successful exploitation can make affected web applications or APIs slow, unstable, or unavailable by exhausting server memory. The risk is most relevant for internet-facing Node.js services that parse attacker-controlled query strings with `qs` and explicitly enable comma parsing. The CVSS and EPSS values indicate relatively low current exploitation likelihood, it is not in CISA KEV, and no ransomware use is reported, but the issue has been public for 178 days and can still affect availability if exposed endpoints accept large query strings.

How an attack unfolds

An attacker identifies an endpoint backed by a Node.js application or framework path that uses `qs.parse()` with `comma: true`. The attacker sends HTTP requests containing one or more query parameters with very long comma-separated values, such as a parameter whose value is mostly repeated commas. Because the vulnerable parser splits the value into an array before enforcing `arrayLimit`, the application allocates memory proportional to the number of comma-separated elements instead of rejecting the input. Repeated or oversized requests can drive high memory use, garbage-collection pressure, process crashes, container restarts, or service-level outages. No authentication or user interaction is required if the vulnerable parsing path is reachable over the network.

How to fix it

Upgrade `ljharb/qs` to a version that includes commit `f6a7abff1f13d644db9b05fe4f2c98ada6bf8482`, or pin directly to that fixed commit where consuming from Git. Deduplicate and update all transitive copies through package-lock, yarn.lock, pnpm-lock.yaml, or equivalent lockfiles. If immediate upgrade is not possible, disable `comma: true` where not strictly required, enforce maximum request-line and query-string sizes at the reverse proxy or application layer, reject parameters with excessive comma counts, set conservative body/query parser limits, and ensure process supervisors impose memory limits with graceful restart behavior. Treat mitigation as defense in depth; the preferred fix is to consume a patched `qs` release or the fixed commit.

How to confirm the fix worked

Confirm exposure by inventorying applications and lockfiles for the `qs` package and verifying whether any code path calls `qs.parse()` or a framework wrapper with `comma: true`. Confirm remediation by checking that the resolved dependency contains commit `f6a7abff1f13d644db9b05fe4f2c98ada6bf8482` or a later release that includes it. In a non-production environment, parse a parameter with more comma-separated elements than the configured `arrayLimit` while `throwOnLimitExceeded` is enabled and verify that the parser enforces the limit rather than returning an oversized array. Also validate that edge controls reject oversized query strings and that SCA/dependency scanning no longer reports the vulnerable `qs` version.

Typical attack path

  1. Find a web application or API endpoint that accepts query-string parameters.
  2. Determine or assume that the backend uses the `qs` package with `comma: true` enabled.
  3. Send a request containing a query parameter with an unusually large number of comma-separated empty or short values.
  4. Trigger `qs.parse()` to call `split(',')` and allocate an oversized array before `arrayLimit` is enforced.
  5. Repeat or enlarge requests until Node.js memory usage spikes, garbage collection stalls, or the process crashes.
  6. Cause user-visible errors, restarts, degraded performance, or temporary service unavailability.

How to detect it

To determine whether exploitation already occurred, review HTTP access logs, CDN/WAF logs, reverse proxy logs, and application request logs for unusually long query strings containing high counts of commas in a single parameter value. Correlate those requests with spikes in Node.js heap usage, garbage-collection pauses, HTTP 500/502/503/504 responses, request timeouts, container OOM kills, systemd or PM2 restarts, Kubernetes pod restarts, and V8 fatal memory errors. In application logs, look for crashes or restarts immediately after requests with comma-dense query parameters. In infrastructure telemetry, review memory metrics and restart events for Node.js services around the same timestamps. If available, preserve suspicious request samples, source IPs, user agents, and heap or crash dumps for scoping, but avoid replaying large payloads against production systems.

  • FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
  • FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
  • JavaScript heap out of memory
  • Allocation failed - JavaScript heap out of memory
  • signal: killed
  • OOMKilled
  • ExitCode:137
  • exit code 137
  • ENOMEM
  • qs.parse
  • comma: true
  • ?,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  • =,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  • HTTP 414
  • Request-URI Too Large
  • Request Header Or Cookie Too Large

What your security team should do

  • Prioritize internet-facing Node.js services and APIs that parse query strings with `qs` and may enable `comma: true`.
  • Upgrade or pin `qs` to a build containing commit `f6a7abff1f13d644db9b05fe4f2c98ada6bf8482`, then rebuild and redeploy affected services.
  • Regenerate lockfiles and container images to eliminate stale or transitive vulnerable copies of `qs`.
  • Add reverse proxy, load balancer, or application rules limiting maximum URL/query-string length and rejecting query parameters with excessive comma density.
  • Review application code for unnecessary `comma: true` usage and disable it unless required by a documented API contract.
  • Monitor for Node.js memory exhaustion, process restarts, and anomalously long comma-heavy query strings, especially on public endpoints.
  • Because this is not KEV-listed and has low EPSS, handle as availability-hardening work unless exposure is confirmed on critical public services, in which case patch promptly.

The record

### Summary The `arrayLimit` option in qs does not enforce limits for comma-separated values when `comma: true` is enabled, allowing attackers to cause denial-of-service via memory exhaustion. This is a bypass of the array limit enforcement, similar to the bracket notation bypass addressed in GHSA-6rw7-vpxm-498p (CVE-2025-15284). ### Details When the `comma` option is set to `true` (not the default, but configurable in applications), qs allows parsing comma-separated strings as arrays (e.g., `?param=a,b,c` becomes `['a', 'b', 'c']`). However, the limit check for `arrayLimit` (default: 20) and the optional throwOnLimitExceeded occur after the comma-handling logic in `parseArrayValue`, enabling a bypass. This permits creation of arbitrarily large arrays from a single parameter, leading to excessive memory allocation. **Vulnerable code** (lib/parse.js: lines ~40-50): ```js if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {     return val.split(','); } if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) {     throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); } return val; ``` The `split(',')` returns the array immediately, skipping the subsequent limit check. Downstream merging via `utils.combine` does not prevent allocation, even if it marks overflows for sparse arrays.This discrepancy allows attackers to send a single parameter with millions of commas (e.g., `?param=,,,,,,,,...`), allocating massive arrays in memory without triggering limits. It bypasses the intent of `arrayLimit`, which is enforced correctly for indexed (`a[0]=`) and bracket (`a[]=`) notations (the latter fixed in v6.14.1 per GHSA-6rw7-vpxm-498p). ### PoC **Test 1 - Basic bypass:** ``` npm install qs ``` ```js const qs = require('qs'); const payload = 'a=' + ','.repeat(25); // 26 elements after split (bypasses arrayLimit: 5) const options = { comma: true, arrayLimit: 5, throwOnLimitExceeded: true }; try {   const result = qs.parse(payload, options);   console.log(result.a.length); // Outputs: 26 (bypass successful) } catch (e) {   console.log('Limit enforced:', e.message); // Not thrown } ``` **Configuration:** - `comma: true` - `arrayLimit: 5` - `throwOnLimitExceeded: true` Expected: Throws "Array limit exceeded" error. Actual: Parses successfully, creating an array of length 26. ### Impact Denial of Service (DoS) via memory exhaustion.

Affected packages

Ecosystem Package Introduced Fixed
Chainguard arangodb-3.11 0 3.11.14.3-r0
Chainguard arangodb-3.12 0 3.12.7.2-r2
Chainguard argo-workflows-ui-3.6 0 3.6.19-r0
Chainguard argo-workflows-ui-3.7 0 3.7.10-r0
Chainguard code-server 0 4.106.3-r5
Chainguard json-server 0 0.17.4-r5
Chainguard kubeflow-centraldashboard 0 1.10.0-r11
Chainguard kubeflow-pipelines-frontend 0 2.15.0-r12
Chainguard langfuse-3 0 3.155.1-r2
Chainguard langfuse-3-worker 0 3.155.1-r2
Chainguard langfuse-fips-3 0 3.155.1-r1
Chainguard langfuse-fips-3-worker 0 3.155.1-r1
Chainguard librechat 0 0.8.3-r1
Chainguard opensearch-dashboards-2 0 2.19.4-r10
Chainguard opensearch-dashboards-2-alerting-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-2-dashboards-notifications 0 2.19.4-r10
Chainguard opensearch-dashboards-2-dashboards-query-workbench 0 2.19.4-r10
Chainguard opensearch-dashboards-2-dashboards-reporting 0 2.19.4-r10
Chainguard opensearch-dashboards-2-dashboards-visualizations 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-alerting-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-dashboards-notifications 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-dashboards-query-workbench 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-dashboards-reporting 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-dashboards-visualizations 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-index-management-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-security-analytics-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-2-fips-security-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-2-index-management-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-2-security-analytics-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-2-security-dashboards-plugin 0 2.19.4-r10
Chainguard opensearch-dashboards-3 0 3.5.0-r1
Chainguard opensearch-dashboards-3-alerting-dashboards-plugin 0 3.5.0-r1
Chainguard opensearch-dashboards-3-dashboards-notifications 0 3.5.0-r1
Chainguard opensearch-dashboards-3-dashboards-query-workbench 0 3.5.0-r1
Chainguard opensearch-dashboards-3-dashboards-reporting 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips-alerting-dashboards-plugin 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips-dashboards-notifications 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips-dashboards-query-workbench 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips-dashboards-reporting 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips-index-management-dashboards-plugin 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips-security-analytics-dashboards-plugin 0 3.5.0-r1
Chainguard opensearch-dashboards-3-fips-security-dashboards-plugin 0 3.5.0-r1
Chainguard opensearch-dashboards-3-index-management-dashboards-plugin 0 3.5.0-r1
Chainguard opensearch-dashboards-3-security-analytics-dashboards-plugin 0 3.5.0-r1
Chainguard opensearch-dashboards-3-security-dashboards-plugin 0 3.5.0-r1
Chainguard pelias-api 0 7.6.0-r2
Chainguard redisinsight 0 3.0.3-r1
Chainguard sqlpad 0 7.5.7-r10
Chainguard thingsboard-tb-js-executor 0 4.3.0.1-r1
Chainguard thingsboard-tb-js-executor-fips 0 4.3.0.1-r1
Chainguard thingsboard-tb-web-ui 0 4.3.0.1-r1
Chainguard thingsboard-tb-web-ui-fips 0 4.3.0.1-r1
Chainguard tileserver-gl 0 5.5.0-r4
Chainguard tileserver-gl-fips 0 5.5.0-r5
Wolfi argo-workflows-ui-3.7 0 3.7.10-r0
Wolfi code-server 0 4.106.3-r5
Wolfi json-server 0 0.17.4-r5
Wolfi kubeflow-centraldashboard 0 1.10.0-r11
Wolfi kubeflow-pipelines-frontend 0 2.15.0-r12
Wolfi langfuse-3 0 3.155.1-r2
Wolfi langfuse-3-worker 0 3.155.1-r2
Wolfi opensearch-dashboards-2 0 2.19.4-r10
Wolfi opensearch-dashboards-2-alerting-dashboards-plugin 0 2.19.4-r10
Wolfi opensearch-dashboards-2-dashboards-notifications 0 2.19.4-r10
Wolfi opensearch-dashboards-2-dashboards-query-workbench 0 2.19.4-r10
Wolfi opensearch-dashboards-2-dashboards-reporting 0 2.19.4-r10
Wolfi opensearch-dashboards-2-dashboards-visualizations 0 2.19.4-r10
Wolfi opensearch-dashboards-2-index-management-dashboards-plugin 0 2.19.4-r10
Wolfi opensearch-dashboards-2-security-analytics-dashboards-plugin 0 2.19.4-r10
Wolfi opensearch-dashboards-2-security-dashboards-plugin 0 2.19.4-r10
Wolfi opensearch-dashboards-3 0 3.5.0-r1
Wolfi opensearch-dashboards-3-alerting-dashboards-plugin 0 3.5.0-r1
Wolfi opensearch-dashboards-3-dashboards-notifications 0 3.5.0-r1
Wolfi opensearch-dashboards-3-dashboards-query-workbench 0 3.5.0-r1
Wolfi opensearch-dashboards-3-dashboards-reporting 0 3.5.0-r1
Wolfi opensearch-dashboards-3-index-management-dashboards-plugin 0 3.5.0-r1
Wolfi opensearch-dashboards-3-security-analytics-dashboards-plugin 0 3.5.0-r1
Wolfi opensearch-dashboards-3-security-dashboards-plugin 0 3.5.0-r1
Wolfi sqlpad 0 7.5.7-r10
Wolfi thingsboard-tb-js-executor 0 4.3.0.1-r1
Wolfi thingsboard-tb-web-ui 0 4.3.0.1-r1
Wolfi tileserver-gl 0 5.5.0-r4

Related vulnerabilities