diff --git a/.changeset/tasty-dingos-breathe.md b/.changeset/tasty-dingos-breathe.md new file mode 100644 index 000000000000..24982895b213 --- /dev/null +++ b/.changeset/tasty-dingos-breathe.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: enable CSRF protection in builds with a non-production `NODE_ENV` value diff --git a/packages/kit/src/runtime/app/server/remote/prerender.js b/packages/kit/src/runtime/app/server/remote/prerender.js index 0391c084da55..d775f3ab5de6 100644 --- a/packages/kit/src/runtime/app/server/remote/prerender.js +++ b/packages/kit/src/runtime/app/server/remote/prerender.js @@ -2,7 +2,6 @@ /** @import { RemotePrerenderInputsGenerator, RemotePrerenderInternals, MaybePromise } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ import { json, error } from '@sveltejs/kit'; -import { DEV } from 'esm-env'; import { get_request_store } from '@sveltejs/kit/internal/server'; import { stringify, stringify_remote_arg } from '../../../shared.js'; import { noop } from '../../../../utils/functions.js'; @@ -99,7 +98,7 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) { const id = __.id; const url = `${base}/${app_dir}/remote/${id}${payload ? `/${payload}` : ''}`; - if (!state.prerendering && !DEV && !event.isRemoteRequest) { + if (!state.prerendering && !__SVELTEKIT_DEV__ && !event.isRemoteRequest) { try { // TODO adapters can provide prerendered data more efficiently than // fetching from the public internet diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index f73a8a156473..b323f560fce0 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -70,7 +70,7 @@ export async function internal_respond(request, options, manifest, state) { const is_data_request = has_data_suffix(url.pathname); const remote_id = get_remote_id(url); - if (!DEV) { + if (!__SVELTEKIT_DEV__) { const request_origin = request.headers.get('origin'); if (remote_id) { diff --git a/packages/kit/test/apps/options-2/test/test.js b/packages/kit/test/apps/options-2/test/test.js index 3ea959f035d3..f627e9adb682 100644 --- a/packages/kit/test/apps/options-2/test/test.js +++ b/packages/kit/test/apps/options-2/test/test.js @@ -165,6 +165,24 @@ test.describe("bundleStrategy: 'single'", () => { }); }); +test.describe('CSRF', () => { + test('blocks cross-origin form submissions when custom NODE_ENV is set', async ({ baseURL }) => { + test.skip(!!process.env.DEV); + + const res = await fetch(`${baseURL}/basepath`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://evil.example' + }, + body: 'foo=bar' + }); + + expect(res.status).toBe(403); + expect(await res.text()).toBe('Cross-site POST form submissions are forbidden'); + }); +}); + test.describe('Vite', () => { // regression test for https://github.com/sveltejs/kit/issues/13249: // user `define`s referenced at the top level of hooks.client.js must be