From e4c1ffacf94f1f4366a886e802dd49f144a89619 Mon Sep 17 00:00:00 2001 From: M <26060677+0x221A@users.noreply.github.com> Date: Sun, 30 Jun 2024 15:17:45 +0700 Subject: [PATCH 1/3] fix: page response missing CSP and Link headers when return promise in `load` (#11801) --- .changeset/tidy-timers-perform.md | 5 +++++ packages/kit/src/runtime/server/page/render.js | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .changeset/tidy-timers-perform.md diff --git a/.changeset/tidy-timers-perform.md b/.changeset/tidy-timers-perform.md new file mode 100644 index 000000000000..b23476a0e3aa --- /dev/null +++ b/.changeset/tidy-timers-perform.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: page response missing CSP and Link headers when return promise in `load` diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index d260eb18e82c..27e1fb51709a 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -511,9 +511,7 @@ export async function render_response({ type: 'bytes' }), { - headers: { - 'content-type': 'text/html' - } + headers } ); } From 068a91446f78109f16cea9c29ae9a0624a214969 Mon Sep 17 00:00:00 2001 From: M <26060677+0x221A@users.noreply.github.com> Date: Sun, 30 Jun 2024 15:49:50 +0700 Subject: [PATCH 2/3] fix: add nonce in stream data part --- packages/kit/src/runtime/server/page/render.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 27e1fb51709a..6c275c6d968e 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -265,6 +265,7 @@ export async function render_response({ event, options, branch.map((b) => b.server_data), + csp, global ); @@ -522,10 +523,11 @@ export async function render_response({ * @param {import('@sveltejs/kit').RequestEvent} event * @param {import('types').SSROptions} options * @param {Array} nodes + * @param {import('./csp.js').Csp} csp * @param {string} global * @returns {{ data: string, chunks: AsyncIterable | null }} */ -function get_data(event, options, nodes, global) { +function get_data(event, options, nodes, csp, global) { let promise_id = 1; let count = 0; @@ -564,7 +566,9 @@ function get_data(event, options, nodes, global) { str = devalue.uneval({ id, data, error }, replacer); } - push(`\n`); + push( + `${global}.resolve(${str})\n` + ); if (count === 0) done(); } ); From c8eb6825bdab3302bf739c7ce46d2a57305aefd1 Mon Sep 17 00:00:00 2001 From: M <26060677+0x221A@users.noreply.github.com> Date: Thu, 10 Oct 2024 13:48:41 +0700 Subject: [PATCH 3/3] test: ensure CSP header in stream response --- .../options/source/pages/csp-with-stream/+page.server.js | 5 +++++ .../options/source/pages/csp-with-stream/+page.svelte | 9 +++++++++ packages/kit/test/apps/options/test/test.js | 9 +++++++++ 3 files changed, 23 insertions(+) create mode 100644 packages/kit/test/apps/options/source/pages/csp-with-stream/+page.server.js create mode 100644 packages/kit/test/apps/options/source/pages/csp-with-stream/+page.svelte diff --git a/packages/kit/test/apps/options/source/pages/csp-with-stream/+page.server.js b/packages/kit/test/apps/options/source/pages/csp-with-stream/+page.server.js new file mode 100644 index 000000000000..968df8f5d440 --- /dev/null +++ b/packages/kit/test/apps/options/source/pages/csp-with-stream/+page.server.js @@ -0,0 +1,5 @@ +export function load() { + return { + lazy: new Promise((resolve) => setTimeout(() => resolve(), 1000)).then(() => 'Moo Deng!') + }; +} diff --git a/packages/kit/test/apps/options/source/pages/csp-with-stream/+page.svelte b/packages/kit/test/apps/options/source/pages/csp-with-stream/+page.svelte new file mode 100644 index 000000000000..ebf0bb40e051 --- /dev/null +++ b/packages/kit/test/apps/options/source/pages/csp-with-stream/+page.svelte @@ -0,0 +1,9 @@ + + +{#await data.lazy} + Loading... +{:then value} +

{value}

+{/await} diff --git a/packages/kit/test/apps/options/test/test.js b/packages/kit/test/apps/options/test/test.js index cce1d30355b4..921c0ef913c1 100644 --- a/packages/kit/test/apps/options/test/test.js +++ b/packages/kit/test/apps/options/test/test.js @@ -130,6 +130,15 @@ test.describe('CSP', () => { expect(await page.evaluate('window.pwned')).toBe(undefined); }); + test('ensure CSP header in stream response', async ({ page, javaScriptEnabled }) => { + if (!javaScriptEnabled) return; + const response = await page.goto('/path-base/csp-with-stream'); + expect(response.headers()['content-security-policy']).toMatch( + /require-trusted-types-for 'script'/ + ); + expect(await page.textContent('h2')).toBe('Moo Deng!'); + }); + test("quotes 'script'", async ({ page }) => { const response = await page.goto('/path-base'); expect(response.headers()['content-security-policy']).toMatch(