diff --git a/.changeset/ninety-clouds-love.md b/.changeset/ninety-clouds-love.md new file mode 100644 index 000000000000..f418a5e0b35b --- /dev/null +++ b/.changeset/ninety-clouds-love.md @@ -0,0 +1,5 @@ +--- +"@sveltejs/kit": patch +--- + +fix: only add nonce to `style-src` CSP directive when `unsafe-inline` is not present \ No newline at end of file diff --git a/packages/kit/src/runtime/server/page/csp.js b/packages/kit/src/runtime/server/page/csp.js index 5eafa314aa6d..547c43cd8835 100644 --- a/packages/kit/src/runtime/server/page/csp.js +++ b/packages/kit/src/runtime/server/page/csp.js @@ -194,7 +194,7 @@ class BaseProvider { this.#style_src_elem.push(`sha256-${hash}`); } } else { - if (this.#style_src.length === 0) { + if (this.#style_src.length === 0 && !d['style-src']?.includes('unsafe-inline')) { this.#style_src.push(`nonce-${this.#nonce}`); } if (d['style-src-attr']?.length) { diff --git a/packages/kit/src/runtime/server/page/csp.spec.js b/packages/kit/src/runtime/server/page/csp.spec.js index 592478db91ab..670d27305065 100644 --- a/packages/kit/src/runtime/server/page/csp.spec.js +++ b/packages/kit/src/runtime/server/page/csp.spec.js @@ -102,6 +102,32 @@ test('skips nonce with unsafe-inline', () => { assert.equal(csp.report_only_provider.get_header(), "default-src 'unsafe-inline'; report-uri /"); }); +test('skips nonce in style-src when using unsafe-inline', () => { + const csp = new Csp( + { + mode: 'nonce', + directives: { + 'style-src': ['self', 'unsafe-inline'] + }, + reportOnly: { + 'style-src': ['self', 'unsafe-inline'], + 'report-uri': ['/'] + } + }, + { + prerender: false + } + ); + + csp.add_style(''); + + assert.equal(csp.csp_provider.get_header(), "style-src 'self' 'unsafe-inline'"); + assert.equal( + csp.report_only_provider.get_header(), + "style-src 'self' 'unsafe-inline'; report-uri /" + ); +}); + test('skips hash with unsafe-inline', () => { const csp = new Csp( {