Skip to content

Commit cd66cd1

Browse files
committed
fix(headers): add ssg hashes for script-src-elem and style-src-elem
1 parent 39369db commit cd66cd1

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

src/runtime/nitro/plugins/50-updateCsp.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ function updateCspVariables(csp: ContentSecurityPolicyValue, nonce?: string, scr
5454
})
5555
.filter(source => source)
5656

57-
if (directive === 'script-src' && scriptHashes) {
57+
if (['script-src', 'script-src-elem'].includes(directive) && scriptHashes) {
5858
modifiedSources.push(...scriptHashes)
5959
}
60-
if (directive === 'style-src' && styleHashes) {
60+
if (['style-src', 'style-src-elem'].includes(directive) && styleHashes) {
6161
modifiedSources.push(...styleHashes)
6262
}
6363

test/fixtures/ssgHashes/nuxt.config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ export default defineNuxtConfig({
66
'/': {
77
prerender: true
88
},
9+
'/inline-elem': {
10+
prerender: true,
11+
security: {
12+
headers: {
13+
contentSecurityPolicy: {
14+
"script-src": false,
15+
"style-src": false,
16+
"script-src-elem": [],
17+
"style-src-elem": []
18+
}
19+
}
20+
}
21+
},
922
'/inline-script': {
1023
prerender: true
1124
},
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<div>
3+
Default page
4+
</div>
5+
</template>
6+
<script setup>
7+
useHead({
8+
script: [
9+
{ textContent: 'window.myImportantVar = 1', type: 'text/javascript' }
10+
],
11+
style: [
12+
{ textContent: 'div { color: blue }', type: 'text/css' }
13+
]
14+
})
15+
</script>

test/ssgHashes.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ describe('[nuxt-security] SSG support of CSP', async () => {
6666
expect(strippedHeaderCsp).toBe(metaCsp)
6767
})
6868

69+
it('sets script- and style-src-elem for inline scripts and styles', async () => {
70+
const res = await fetch('/inline-elem')
71+
72+
const body = await res.text()
73+
const { csp } = extractDataFromBody(body)
74+
75+
expect(csp).toMatch(/script-src-elem[^;]+'sha256-/)
76+
expect(csp).toMatch(/style-src-elem[^;]+'sha256-/)
77+
})
78+
6979
it('sets script-src for inline scripts', async () => {
7080
const res = await fetch('/inline-script')
7181

@@ -88,7 +98,7 @@ describe('[nuxt-security] SSG support of CSP', async () => {
8898
const res = await fetch('/inline-script-with-linebreak')
8999
const body = await res.text()
90100
const { metaTag, csp, elementsWithIntegrity, inlineScriptHashes, externalScriptHashes, inlineStyleHashes, externalStyleHashes } = extractDataFromBody(body)
91-
101+
92102
expect(res).toBeDefined()
93103
expect(res).toBeTruthy()
94104
expect(body).toBeDefined()
@@ -263,4 +273,4 @@ describe('[nuxt-security] SSG support of CSP', async () => {
263273
expect(body).toBeDefined()
264274
expect(body).toMatch(/^<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="Content-Security-Policy"/)
265275
})
266-
})
276+
})

0 commit comments

Comments
 (0)