From d1b639cbb4a6724e697dce99da062966942c580e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 3 Jun 2022 09:37:49 -0400 Subject: [PATCH] prevent accessing /__data.json for standalone endpoint --- packages/kit/src/runtime/server/index.js | 31 ++++++++++++------- .../src/routes/endpoint-output/simple.js | 7 +++++ packages/kit/test/apps/basics/test/test.js | 11 +++++++ 3 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 packages/kit/test/apps/basics/src/routes/endpoint-output/simple.js diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index 692b73aa66b7..c10bbacdd937 100644 --- a/packages/kit/src/runtime/server/index.js +++ b/packages/kit/src/runtime/server/index.js @@ -80,19 +80,26 @@ export async function respond(request, options, state) { } } - if (route?.type === 'page') { - const normalized = normalize_path(url.pathname, options.trailing_slash); - - if (normalized !== url.pathname && !state.prerendering?.fallback) { + if (route) { + if (route.type === 'page') { + const normalized = normalize_path(url.pathname, options.trailing_slash); + + if (normalized !== url.pathname && !state.prerendering?.fallback) { + return new Response(undefined, { + status: 301, + headers: { + 'x-sveltekit-normalize': '1', + location: + // ensure paths starting with '//' are not treated as protocol-relative + (normalized.startsWith('//') ? url.origin + normalized : normalized) + + (url.search === '?' ? '' : url.search) + } + }); + } + } else if (is_data_request) { + // requesting /__data.json should fail for a standalone endpoint return new Response(undefined, { - status: 301, - headers: { - 'x-sveltekit-normalize': '1', - location: - // ensure paths starting with '//' are not treated as protocol-relative - (normalized.startsWith('//') ? url.origin + normalized : normalized) + - (url.search === '?' ? '' : url.search) - } + status: 404 }); } } diff --git a/packages/kit/test/apps/basics/src/routes/endpoint-output/simple.js b/packages/kit/test/apps/basics/src/routes/endpoint-output/simple.js new file mode 100644 index 000000000000..183ff6652837 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/endpoint-output/simple.js @@ -0,0 +1,7 @@ +export function get() { + return { + body: { + answer: 42 + } + }; +} diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index d5c7de9372c6..cb159068c791 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -760,6 +760,17 @@ test.describe.parallel('Endpoints', () => { 'name=SvelteKit; path=/; HttpOnly' ]); }); + + test('Standalone endpoint is not accessible via /__data.json suffix', async ({ request }) => { + const r1 = await request.get('/endpoint-output/simple', { + headers: { accept: 'application/json' } + }); + + expect(await r1.json()).toEqual({ answer: 42 }); + + const r2 = await request.get('/endpoint-output/simple/__data.json'); + expect(r2.status()).toBe(404); + }); }); test.describe.parallel('Encoded paths', () => {