High severity7.5NVD Advisory· Published Apr 10, 2026· Updated Apr 15, 2026
CVE-2026-40073
CVE-2026-40073
Description
SvelteKit is a framework for rapidly developing robust, performant web applications using Svelte. Prior to 2.57.1, under certain circumstances, requests could bypass the BODY_SIZE_LIMIT on SvelteKit applications running with adapter-node. This bypass does not affect body size limits at other layers of the application stack, so limits enforced in the WAF, gateway, or at the platform level are unaffected. This vulnerability is fixed in 2.57.1.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@sveltejs/kitnpm | < 2.57.1 | 2.57.1 |
Affected products
1Patches
13 files changed · +103 −5
.changeset/fair-chefs-strive.md+5 −0 added@@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: enforce `BODY_SIZE_LIMIT` on chunked requests
packages/kit/src/exports/node/index.js+17 −5 modified@@ -16,10 +16,11 @@ function get_raw_body(req, body_size_limit) { } const content_length = Number(h['content-length']); + const has_content_length = Number.isFinite(content_length); // check if no request body if ( - (req.httpVersionMajor === 1 && isNaN(content_length) && h['transfer-encoding'] == null) || + (req.httpVersionMajor === 1 && !has_content_length && h['transfer-encoding'] == null) || content_length === 0 ) { return null; @@ -36,7 +37,7 @@ function get_raw_body(req, body_size_limit) { return new ReadableStream({ start(controller) { - if (body_size_limit !== undefined && content_length > body_size_limit) { + if (body_size_limit !== undefined && has_content_length && content_length > body_size_limit) { let message = `Content-length of ${content_length} exceeds limit of ${body_size_limit} bytes.`; if (body_size_limit === 0) { @@ -65,11 +66,22 @@ function get_raw_body(req, body_size_limit) { if (cancelled) return; size += chunk.length; - if (size > content_length) { + + if (body_size_limit !== undefined && size > body_size_limit) { + cancelled = true; + + const message = `request body size exceeded BODY_SIZE_LIMIT of ${body_size_limit}`; + + const error = new SvelteKitError(413, 'Payload Too Large', message); + controller.error(error); + + return; + } + + if (has_content_length && size > content_length) { cancelled = true; - const constraint = content_length ? 'content-length' : 'BODY_SIZE_LIMIT'; - const message = `request body size exceeded ${constraint} of ${content_length}`; + const message = `request body size exceeded content-length of ${content_length}`; const error = new SvelteKitError(413, 'Payload Too Large', message); controller.error(error);
packages/kit/src/exports/node/index.spec.js+81 −0 added@@ -0,0 +1,81 @@ +import { PassThrough } from 'node:stream'; +import { expect, test } from 'vitest'; +import { getRequest } from './index.js'; + +/** + * @param {{ + * headers?: Record<string, string>; + * bodySizeLimit?: number; + * }} [options] + */ +async function create_request(options = {}) { + const req = new PassThrough(); + const incoming = /** @type {import('http').IncomingMessage} */ (/** @type {unknown} */ (req)); + + incoming.headers = { + 'content-type': 'text/plain', + ...options.headers + }; + incoming.method = 'POST'; + incoming.url = '/'; + incoming.httpVersionMajor = 1; + + return { + request: await getRequest({ + request: incoming, + base: 'http://localhost', + bodySizeLimit: options.bodySizeLimit + }), + req + }; +} + +test('rejects chunked request bodies that exceed body size limit', async () => { + const { request, req } = await create_request({ + headers: { 'transfer-encoding': 'chunked' }, + bodySizeLimit: 10 + }); + + const text = request.text(); + + req.write(Buffer.from('0123456789')); + req.write(Buffer.from('x')); + req.end(); + + await expect(text).rejects.toMatchObject({ + status: 413, + text: 'Payload Too Large', + message: 'request body size exceeded BODY_SIZE_LIMIT of 10' + }); +}); + +test('allows chunked request bodies within body size limit', async () => { + const { request, req } = await create_request({ + headers: { 'transfer-encoding': 'chunked' }, + bodySizeLimit: 10 + }); + + const text = request.text(); + + req.write(Buffer.from('0123456789')); + req.end(); + + await expect(text).resolves.toBe('0123456789'); +}); + +test('rejects request bodies that exceed content-length', async () => { + const { request, req } = await create_request({ + headers: { 'content-length': '4' } + }); + + const text = request.text(); + + req.write(Buffer.from('01234')); + req.end(); + + await expect(text).rejects.toMatchObject({ + status: 413, + text: 'Payload Too Large', + message: 'request body size exceeded content-length of 4' + }); +});
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/sveltejs/kit/commit/3202ed6c98f9e8d86bf0c4c7ad0f2e273e5e3b95nvdPatchWEB
- github.com/advisories/GHSA-2crg-3p73-43xpghsaADVISORY
- github.com/sveltejs/kit/security/advisories/GHSA-2crg-3p73-43xpnvdVendor AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2026-40073ghsaADVISORY
- github.com/sveltejs/kit/releases/tag/%40sveltejs%2Fkit%402.57.1ghsaWEB
- github.com/sveltejs/kit/releases/tag/@sveltejs/kit@2.57.1nvdProductRelease NotesWEB
News mentions
0No linked articles in our index yet.