Skip to main content
Vulnerability Database/CVE-2026-92708

CVE-2026-92708: Svelte Devalue Information Disclosure

CVE-2026-92708 is an information disclosure flaw in Svelte devalue that exposes up to 64 KB of unrelated process memory during serialization. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-92708 Overview

CVE-2026-92708 is an information disclosure vulnerability in Svelte devalue, a JavaScript library that serializes values into strings when JSON.stringify is insufficient. The stringify and uneval functions serialize typed arrays by emitting the entire backing ArrayBuffer rather than only the view. When applications serialize a Node Buffer, whose backing store is a process-wide shared pool, up to 64 KB of unrelated process memory can be disclosed. Server-side-rendered frameworks such as SvelteKit or Nuxt are directly impacted, since a public page whose load() returns a small Buffer can ship another user's request body or Authorization header in its HTML.

Critical Impact

Unauthenticated remote attackers can retrieve sensitive process memory, including credentials and other users' in-flight request data, on every affected server render.

Affected Products

  • Svelte devalue versions 5.1.0 through 5.9.2
  • SvelteKit applications using vulnerable devalue versions with Node Buffer in load() returns
  • Nuxt and other SSR frameworks depending on affected devalue releases

Discovery Timeline

  • 2026-09-18 - CVE-2026-92708 published to NVD
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-92708

Vulnerability Analysis

The vulnerability is classified under [CWE-200] Information Exposure. The stringify and uneval functions in devalue handle typed arrays by serializing the underlying ArrayBuffer in full, not just the view window defined by byteOffset and byteLength. Node's Buffer class allocates from a shared internal pool (Buffer.allocUnsafe and small allocations from Buffer.from). A 100-byte Buffer may sit inside an 8 KB pooled ArrayBuffer containing bytes written by unrelated code paths, including concurrent HTTP requests. Serialization emits the entire pool slab, embedding foreign memory contents into rendered HTML delivered to any client that requests the page.

Root Cause

The root cause is an incorrect view-to-buffer mapping in devalue's typed array handling. The library treated the buffer property of a typed array as the intended payload rather than restricting output to view.byteOffset through view.byteOffset + view.byteLength. Because Node Buffer extends Uint8Array and shares a process-wide pool for small allocations, this design leaks pool residue on every render.

Attack Vector

Exploitation is unauthenticated and network-based. An attacker repeatedly requests any SSR page whose server-side data function returns a small Buffer or reads a small file. The rendered HTML contains base64 or numeric encoding of the entire pooled slab, which may include headers, session tokens, or request bodies from other concurrent users. The issue fires on every render and is not mitigated by parse or unflatten prototype-pollution and denial-of-service guards, which only apply when parsing untrusted input.

javascript
// Security patch in src/operations.js - imports helper to detect Node Buffer
 import {
 	enumerable_symbols,
 	get_type,
+	is_buffer,
 	is_plain_object,
 	valid_array_indices
 } from './utils.js';

Source: GitHub Commit 46dc877

typescript
// Security patch in src/types.d.ts - documents corrected viewInfo semantics
 	/**
 	 * Returns the view metadata of a typed array or `DataView` value.
 	 * `length` is only meaningful for typed arrays. `buffer` is serialized
-	 * recursively, so it may be a foreign value/handle.
+	 * recursively in full, so it may be a foreign value/handle.
+	 * The default copies Node Buffers into an exact-sized backing buffer with
+	 * byteOffset 0 to avoid exposing unrelated bytes from Node's shared pool.
+	 * Overrides must take equivalent care with pooled views.
 	 */
 	viewInfo(view: any): {
 		buffer: any;

Source: GitHub Commit 46dc877

Detection Methods for CVE-2026-92708

Indicators of Compromise

  • Rendered HTML pages containing unexpectedly large base64 or numeric arrays inside serialized SSR payloads
  • Presence of authentication headers, cookies, or request body fragments belonging to other users in publicly cached HTML
  • SSR responses whose payload size grows disproportionately relative to the declared Buffer length

Detection Strategies

  • Audit dependency manifests for devalue versions between 5.1.0 and 5.9.2 across all Node.js services
  • Grep application code for Buffer values passed to devalue.stringify, devalue.uneval, or returned from SvelteKit load() and Nuxt asyncData functions
  • Compare emitted typed array lengths against expected byteLength values in test harnesses to surface pool-slab leakage

Monitoring Recommendations

  • Log and alert on outbound HTML response sizes that deviate from historical baselines for SSR routes
  • Instrument SSR renderers to fingerprint sensitive tokens (JWTs, API keys) leaving the process boundary in HTML bodies
  • Scan CDN and cache layers for stored SSR responses containing Authorization, Cookie, or Set-Cookie fragment patterns

How to Mitigate CVE-2026-92708

Immediate Actions Required

  • Upgrade devalue to version 5.9.3 or later across all applications and transitive dependencies
  • Invalidate SSR-rendered pages held in CDN or reverse-proxy caches that were generated with a vulnerable version
  • Rotate credentials, session tokens, and API keys that may have transited affected servers during the exposure window

Patch Information

The issue is fixed in devalue5.9.3. The patch introduces an is_buffer helper and updates viewInfo to copy Node Buffer values into an exact-sized backing buffer with byteOffset 0, eliminating pool residue in the serialized output. See the GitHub Release v5.9.3 and GHSA-j22f-vq7h-c4qm for full details.

Workarounds

  • Convert Node Buffer objects to Uint8Array via new Uint8Array(buf) before passing them to devalue.stringify or devalue.uneval
  • Avoid returning Buffer values directly from SvelteKit load() or Nuxt server data functions until the upgrade is deployed
  • Replace small file reads that produce pooled Buffer output with explicit unpooled allocations using Buffer.allocUnsafeSlow
bash
# Upgrade devalue to the patched release
npm install devalue@5.9.3

# Verify no transitive dependency pins a vulnerable range
npm ls devalue

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.