Feb 19, 2026·5 min read·20 visits
SvelteKit's experimental remote functions feature trusts user-supplied JSON for file offsets. Attackers can send nested arrays instead of numbers, triggering JavaScript type coercion that expands a 1MB payload into ~15GB of memory usage, crashing the server immediately.
A denial-of-service vulnerability in SvelteKit's experimental 'remote functions' feature allows attackers to crash the server via memory exhaustion. By manipulating a JSON-encoded 'file offset table' within a custom binary form payload, an attacker can trigger JavaScript type coercion that expands a small payload into gigabytes of string data, overwhelming the Node.js heap.
In the world of web frameworks, 'experimental' is often just a polite synonym for 'un-audited.' SvelteKit, the darling of the modern frontend world, introduced a feature called remote functions to handle server-side logic invoked directly from the client. To make this efficient, they cooked up a custom content type: application/x-svelte-binary-form.
Whenever a developer sees a custom binary protocol being parsed by a high-level language like JavaScript, their ears should perk up. It means the framework is taking raw bytes and trying to turn them into structured objects. And as we all know, if you don't strictly validate what those bytes represent before you start casting them to types, you're asking for trouble.
This vulnerability is a classic case of trusting the input. The parser assumes it's getting a nice, orderly list of numbers. Instead, we're going to feed it a recursive nightmare.
The vulnerability lives in src/runtime/form-utils.js, specifically within the deserialize_binary_form function. This function is responsible for unpacking that custom binary format. Part of this format includes a file offset table—essentially a map telling the server where file data begins and ends in the byte stream.
To parse this table, SvelteKit did something incredibly simple. Too simple:
// The vulnerable code
file_offsets = /** @type {Array<number>} */ (
JSON.parse(text_decoder.decode(file_offsets_buffer))
);See the problem? They run JSON.parse() and then immediately cast it to Array<number> via JSDoc comments. But JSDoc is a build-time lie; it doesn't exist at runtime. JSON.parse() will happily parse anything valid JSON—strings, objects, or, most critically, nested arrays.
The code assumes file_offsets is a flat array of integers. It does not check. It just blindly passes this data downstream to the logic that constructs file objects.
Let's look at the diff. The fix is a textbook example of "oops, we forgot to check the types."
Before the fix, the code was cowboy-style:
file_offsets = JSON.parse(text_decoder.decode(file_offsets_buffer));After the fix (Commit f47c01bd8100328c24fdb8522fe35913b0735f35), sanity is restored:
const parsed_offsets = JSON.parse(text_decoder.decode(file_offsets_buffer));
if (
!Array.isArray(parsed_offsets) ||
parsed_offsets.some((n) => typeof n !== 'number' || !Number.isInteger(n) || n < 0)
) {
throw deserialize_error('invalid file offset table');
}
file_offsets = parsed_offsets;The patch explicitly validates that:
number.Without this check, file_offsets could contain [[1e20, 1e20]], which is syntactically valid JSON but disastrous for the logic that follows.
So, how do we turn a wrong type into a server crash? Welcome to the horrors of JavaScript type coercion.
When the SvelteKit runtime tries to use these "offsets" to initialize File or Blob objects, it inadvertently performs operations that trigger string conversion. If you pass a nested array (e.g., [1e20, 1e20]) into a context expecting a primitive, JavaScript often calls .toString() on it.
Here is the attack flow:
[[1e20, 1e20, ...]]. We fill this inner array with massive numbers.Array.toString() joins elements with commas.A relatively small payload (1MB) containing a dense array of these numbers converts into a string representation that is gigabytes in size. The Node.js heap, which usually defaults to a few GBs, fills up instantly.
> [!NOTE] > A 1MB payload was observed to spike memory usage to 14.7 GB before the process died. This is an amplification factor of roughly 14,000x.
The console will spit out Fatal error: Ineffective mark-compacts near heap limit Allocation failed, and the process dies. If you don't have an auto-restarter (or if the attacker puts this in a loop), your service is effectively dead.
The remediation is straightforward: Update to @sveltejs/kit 2.52.2.
If you cannot update immediately, you have two options:
application/x-svelte-binary-form requests. The JSON offset table is usually near the start of the body. If you see nested brackets [[ inside the JSON structure, drop the packet.But seriously, just patch it. This is a logic error in the runtime, and no amount of firewall rules will be as effective as code that actually checks its inputs.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
@sveltejs/kit Svelte | >= 2.49.0, <= 2.52.1 | 2.52.2 |
| Attribute | Detail |
|---|---|
| CWE | CWE-770 (Allocation of Resources Without Limits) |
| Attack Vector | Network (POST Request) |
| CVSS | 7.5 (High) |
| Impact | Denial of Service (Memory Exhaustion) |
| Affected Component | form-utils.js (deserialize_binary_form) |
| Exploit Status | Proof of Concept Available |
Allocation of Resources Without Limits or Throttling
CVE-2022-0492 is a high-severity missing authorization vulnerability in the Linux kernel's Control Groups (cgroups) v1 implementation. The flaw resides within the cgroup_release_agent_write function in kernel/cgroup/cgroup-v1.c, where the kernel fails to validate if the process writing to the release_agent file possesses administrative capabilities in the initial user namespace. This allows a local attacker inside a container with root privileges (UID 0) to abuse user namespaces, mount a cgroups v1 directory, modify the release_agent parameter, and execute arbitrary commands on the host system as host root, effectively achieving a complete container escape.
NocoDB is subject to an insufficient session expiration vulnerability where OAuth access and refresh tokens are not invalidated or revoked during security-sensitive actions such as password changes, forgot-password requests, or password resets. This allows an attacker possessing an active OAuth token to maintain unauthorized persistence.
A vulnerability in the vantage6 federated learning framework allows unauthenticated remote attackers to gain administrative control of the server via hardcoded default credentials (root/root) when deployed under default configurations in versions 4.2.3 and below.
An improper access control vulnerability in the vantage6 node component allows concurrently running algorithm containers to read and modify sensitive input and output files of other tasks. The lack of strict workspace directory isolation exposes a significant attack surface in multi-tenant or federated environments where untrusted algorithms are executed.
TinyMCE versions 6.8.0 through 7.0.1 contain a high-severity Cross-Site Scripting (XSS) vulnerability. The flaw exists in the custom HTML parser and sanitizer module, which incorrectly manages SVG namespace scopes when parsing nested elements. A low-privileged or unauthenticated attacker can submit a crafted HTML payload containing nested SVG structures to bypass sanitization filters, leading to arbitrary JavaScript execution in the context of the victim's browser session.
CVE-2026-47759 is a critical stored Cross-Site Scripting (XSS) vulnerability affecting multiple active branches of the TinyMCE rich text editor. The flaw resides in the editor's handling of user-controlled, prefixed internal attributes, such as data-mce-href, data-mce-src, and data-mce-style. When processing raw HTML inputs, TinyMCE's internal validation schema neglects to inspect these custom prefixed attributes. During HTML serialization, the editor's engine extracts these unsanitized values and copies them back into standard executable attributes, overwriting any previously sanitized standard values and leading to execution of arbitrary code.