CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-33HQ-FVWR-56PM

The Billion-Comma Attack: Nuking Svelte SSR with Sparse Arrays

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 20, 2026·6 min read·29 visits

Executive Summary (TL;DR)

Versions of `devalue` prior to 5.6.3 iterate linearly over sparse arrays during serialization. An attacker can define an array with a length of 100 million containing a single item, causing the server to hang while generating a massive string of hole sentinels. The fix introduces a cost-based heuristic to switch to a 'sparse' encoding format when efficient.

A critical algorithmic complexity vulnerability in the `devalue` library, a staple of the Svelte ecosystem, allows attackers to trigger Denial of Service (DoS) via memory exhaustion. By supplying specially crafted sparse arrays—arrays with massive lengths but few actual elements—attackers can force the serialization engine into an O(L) operation (where L is length) rather than O(N) (where N is elements). This results in the server attempting to allocate gigabytes of memory to represent 'empty' space.

The Hook: The Nothing That Kills You

In the world of Server-Side Rendering (SSR), data serialization is the bridge between the server's brain and the client's browser. You calculate the state on the backend, freeze it into a string, ship it over the wire, and rehydrate it on the frontend. Svelte (and SvelteKit) relies heavily on a library called devalue for this task. Unlike JSON.stringify, devalue is smart—it handles circular references, undefined, Map, Set, and BigInt.

But sometimes, trying to be too smart makes you stupid. The vulnerability we're looking at today isn't about malicious code injection or prototype pollution. It's about nothing. Literally.

JavaScript arrays are weird. You can have an array with a length of a billion, but only one actual value at index 0. This is a "sparse array." To the runtime, it's just an object with a length property and a few keys. But if you try to iterate over it like a dense list, you're going to have a bad time. devalue walked right into this trap, treating the void as something that needed to be exhaustively cataloged.

The Flaw: The Linear Fallacy

The root cause is a classic algorithmic complexity error: confusing array.length with the amount of data present. Prior to version 5.6.3, devalue utilized a standard linear loop to process arrays. Whether the array was dense ([1, 2, 3]) or sparse ([1, <99 empty>, 2]), the logic remained the same.

Here is the logic flaw in pseudocode:

// The naive approach
for (let i = 0; i < array.length; i++) {
  if (i in array) {
    serialize(array[i]);
  } else {
    // Write a "hole" sentinel
    output.push(HOLE);
  }
}

See the problem? If array.length is 100,000,000, the loop runs 100 million times. It doesn't matter if the array is empty; the loop condition checks the length, not the keys. In devalue, the HOLE constant (represented as -2 in the serialized output) serves as a placeholder for these empty spots.

So, if an attacker sends a payload containing const arr = []; arr[1e8] = 1;, devalue attempts to generate an internal array containing 99,999,999 -2 integers. This explodes memory usage instantly, turning a 1-byte payload into a multi-gigabyte allocation on the heap.

The Code: Anatomy of a Fix

The patch provided in commit 819f1ac7475ab37547645cfb09bf2f678a799cf0 is a masterclass in defensive coding for serialization. The maintainers didn't just cap the array length; they implemented a cost-based heuristic to determine the most efficient way to represent the data.

The fix introduces a new concept: SPARSE encoding (sentinel -7). Instead of writing out every hole, the serializer now calculates two costs:

  1. Dense Cost: The size of writing every hole plus values.
  2. Sparse Cost: The size of writing index-value pairs + overhead.

Let's look at the logic introduced in stringify.js:

// New heuristic in stringify.js
let dense_cost = 0;
let sparse_cost = 0;
 
for (const index in value) { // Iterates ONLY keys, not length!
  // Calculate cost of values...
}
 
// Calculate cost of holes for dense representation
dense_cost += (value.length - keys.length) * 3; // 3 chars for holes like ",,,"
 
if (sparse_cost < dense_cost) {
  // Switch to SPARSE mode
  str = `[${SPARSE},${value.length},${encoded_sparse_values}]`;
} else {
  // Use standard dense mode
}

This is brilliant. It uses for (const index in value) to iterate only the populated keys. If the array is mostly empty, sparse_cost wins, and the output becomes a compact list of indices and values: [-7, 100000000, 0, "my_value"]. No billion-iteration loop, no memory explosion.

The Exploit: Weaponizing the Void

Exploiting this is trivially easy and requires zero authentication if the target application exposes an endpoint that accepts JSON (or other structures) and renders it via SSR. While JSON.parse creates dense arrays usually, an attacker might bypass this if the input is processed or generated dynamically, or if the system uses devalue to serialize internal state that can be manipulated by user input (like session data or cart items).

Here is a Proof of Concept (PoC) that demonstrates the hang:

const devalue = require('devalue');
 
// 1. Create a "bomb"
// A sparse array with a massive length but only one element.
const sparseBomb = [];
sparseBomb[99999999] = 'Goodbye Memory';
 
console.log("[+] Detonating sparse array bomb...");
console.time("Explosion Duration");
 
try {
  // 2. Trigger the vulnerability
  // This will try to allocate ~300MB+ for the string builder array immediately,
  // then iterate 100 million times.
  const serialized = devalue.stringify(sparseBomb);
  console.log("Serialized length: " + serialized.length);
} catch (e) {
  console.log("[!] Crash confirmed: " + e.message);
}
 
console.timeEnd("Explosion Duration");

On a standard single-threaded Node.js server, this operation blocks the event loop completely. CPU usage spikes to 100%, and the Garbage Collector (GC) goes into a panic spiral trying to reclaim memory, eventually leading to a process crash or a frozen server that stops responding to health checks.

The Impact: Server-Side Suicide

The impact here is a high-reliability Denial of Service (DoS). Because Node.js is single-threaded, a CPU-bound loop like this doesn't just slow down the request that caused it—it stops the entire server from processing any requests.

In a Kubernetes environment, the liveness probe will fail, causing the pod to restart. If the attacker simply sends this payload continuously (or in a loop), they can keep the pods in a perpetual state of crashing and restarting (CrashLoopBackOff).

Why is this juicy? It typically bypasses standard WAF rules. WAFs look for SQL injection (' OR 1=1), XSS (<script>), or command injection (|| whoami). They rarely inspect the length property of a JSON array or the semantic "sparseness" of a data structure. It's a logic bomb that looks like valid data.

The Fix: Patching the Leak

The mitigation is straightforward: upgrade devalue immediately.

Remediation Steps:

  1. Check your package-lock.json or yarn.lock for devalue.
  2. If you are using Svelte or SvelteKit, you likely have this as a transitive dependency.
  3. Run npm update devalue or yarn upgrade devalue.
  4. Ensure the installed version is 5.6.3 or higher.

If you cannot upgrade immediately, you must validate input arrays before they reach the serialization step. Specifically, reject arrays where array.length is significantly larger than Object.keys(array).length (a high sparseness factor), or simply enforce a hard limit on array.length for any user-controlled data.

Official Patches

SvelteJSCommit 819f1ac implementing sparse encoding

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

Svelte (via devalue dependency)SvelteKit (via devalue dependency)Any Node.js application using `devalue` for serialization

Affected Versions Detail

Product
Affected Versions
Fixed Version
devalue
sveltejs
< 5.6.35.6.3
AttributeDetail
Vulnerability TypeAlgorithmic Complexity / Resource Exhaustion
CWE IDCWE-400 (Uncontrolled Resource Consumption)
CVSS7.5 (High)
Attack VectorNetwork (Remote)
Affected Componentdevalue.stringify, devalue.uneval
Fix Commit819f1ac7475ab37547645cfb09bf2f678a799cf0

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
T1499.003Application Exhaustion Flood
Impact
CWE-400
Uncontrolled Resource Consumption

The software does not properly control the allocation of resources, allowing an attacker to cause a Denial of Service by exhausting available memory or CPU.

Known Exploits & Detection

ManualConstructing a sparse array with `arr[1e9]=1` and passing it to `stringify` triggers the hang.

Vulnerability Timeline

Fix commit merged to master
2026-02-18
Release v5.6.3 published to npm
2026-02-18
GHSA-33HQ-FVWR-56PM published
2026-02-19

References & Sources

  • [1]GitHub Advisory GHSA-33HQ-FVWR-56PM
  • [2]devalue v5.6.3 Release Notes

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•1 day ago•GHSA-7PPR-R889-MCF2
7.5

GHSA-7PPR-R889-MCF2: Unbounded WebSocket Message Aggregation in http4s-blaze-server leads to Denial of Service

An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.

Alon Barad
Alon Barad
7 views•5 min read
•1 day ago•GHSA-95CV-R8X4-VH75
7.6

GHSA-95cv-r8x4-vh75: Path Traversal Vulnerability in OpenList Batch Rename Handler

A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.

Amit Schendel
Amit Schendel
8 views•7 min read
•1 day ago•GHSA-P6PH-3JX2-3337
4.3

GHSA-P6PH-3JX2-3337: Horizontal Privilege Escalation and Metadata Information Disclosure via Bleve Search in OpenList

OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.

Amit Schendel
Amit Schendel
8 views•5 min read
•1 day ago•GHSA-86CX-WWF4-PHQ4
6.5

GHSA-86cx-wwf4-phq4: Path Prefix Confusion Authorization Bypass in OpenList

An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.

Amit Schendel
Amit Schendel
7 views•6 min read
•1 day ago•CVE-2026-16584
7.0

CVE-2026-16584: Security Policy Bypass in AWS API MCP Server via Startup Initialization Failure

A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.

Amit Schendel
Amit Schendel
11 views•7 min read
•1 day ago•GHSA-6V4M-FW66-8R4X
6.5

GHSA-6V4M-FW66-8R4X: Path Disclosure and Shell Expansion Bypass in Shescape

An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.

Alon Barad
Alon Barad
6 views•7 min read