Skip to content

Commit

Permalink
Merge pull request #478 from hlhc/fix/ssg-hash-inline-regex
Browse files Browse the repository at this point in the history
fix(csp): inline script/style have whitespace character
  • Loading branch information
Baroshem authored Jun 24, 2024
2 parents fd47d83 + 4aede1b commit 1dd0496
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/runtime/nitro/plugins/30-cspSsgHashes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { generateHash } from '../../../utils/hash'
import type { Section } from '../../../types/module'


const INLINE_SCRIPT_RE = /<script(?![^>]*?\bsrc="[\w:.\-\\/]+")[^>]*>(.*?)<\/script>/gi
const STYLE_RE = /<style[^>]*>(.*?)<\/style>/gi
const INLINE_SCRIPT_RE = /<script(?![^>]*?\bsrc="[\w:.\-\\/]+")[^>]*>([\s\S]*?)<\/script>/gi
const STYLE_RE = /<style[^>]*>([\s\S]*?)<\/style>/gi
const SCRIPT_RE = /<script(?=[^>]+\bsrc="[^"]+")(?=[^>]+\bintegrity="([\w\-+/=]+)")[^>]+(?:\/>|><\/script[^>]*?>)/gi
const LINK_RE = /<link(?=[^>]+\brel="(stylesheet|preload|modulepreload)")(?=[^>]+\bintegrity="([\w\-+/=]+)")(?=(?:[^>]+\bas="(\w+)")?)[^>]+>/gi

Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/ssgHashes/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ export default defineNuxtConfig({
'/inline-script': {
prerender: true
},
'/inline-script-with-linebreak': {
prerender: true
},
'/inline-style': {
prerender: true
},
'/inline-style-with-linebreak': {
prerender: true
},
'/external-script': {
prerender: true
},
Expand Down
19 changes: 19 additions & 0 deletions test/fixtures/ssgHashes/pages/inline-script-with-linebreak.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<div>Default page</div>
</template>
<script setup>
useHead({
script: [
{
textContent: `
window.myImportantVar = 1
`,
type: 'text/javascript'
}
]
})
</script>
15 changes: 15 additions & 0 deletions test/fixtures/ssgHashes/pages/inline-style-with-linebreak.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<div>Default page</div>
</template>
<script setup>
useHead({
style: [
{
textContent: `
div { color: blue }
`,
type: 'text/css'
}
]
})
</script>
35 changes: 35 additions & 0 deletions test/ssgHashes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ describe('[nuxt-security] SSG support of CSP', async () => {
expect(externalStyleHashes).toBe(expectedExternalStyleHashes)
})

it('sets script-src for inline scripts with line break', async () => {
const res = await fetch('/inline-script-with-linebreak')
const body = await res.text()
const { metaTag, csp, elementsWithIntegrity, inlineScriptHashes, externalScriptHashes, inlineStyleHashes, externalStyleHashes } = extractDataFromBody(body)

expect(res).toBeDefined()
expect(res).toBeTruthy()
expect(body).toBeDefined()
expect(metaTag).toBeDefined()
expect(csp).toBeDefined()
expect(elementsWithIntegrity).toBe(expectedIntegrityAttributes)
expect(inlineScriptHashes).toBe(expectedInlineScriptHashes + 1) // Inlined script in head
expect(externalScriptHashes).toBe(expectedExternalScriptHashes + 1) // + 1 vue modulepreload
expect(inlineStyleHashes).toBe(expectedInlineStyleHashes)
expect(externalStyleHashes).toBe(expectedExternalStyleHashes)
})

it('sets style-src for inline styles', async () => {
const res = await fetch('/inline-style')

Expand All @@ -102,6 +119,24 @@ describe('[nuxt-security] SSG support of CSP', async () => {
expect(externalStyleHashes).toBe(expectedExternalStyleHashes)
})

it('sets style-src for inline styles with line break', async () => {
const res = await fetch('/inline-style-with-linebreak')

const body = await res.text()
const { metaTag, csp, elementsWithIntegrity, inlineScriptHashes, externalScriptHashes, inlineStyleHashes, externalStyleHashes } = extractDataFromBody(body)

expect(res).toBeDefined()
expect(res).toBeTruthy()
expect(body).toBeDefined()
expect(metaTag).toBeDefined()
expect(csp).toBeDefined()
expect(elementsWithIntegrity).toBe(expectedIntegrityAttributes)
expect(inlineScriptHashes).toBe(expectedInlineScriptHashes)
expect(externalScriptHashes).toBe(expectedExternalScriptHashes + 1) // + 1 vue modulepreload
expect(inlineStyleHashes).toBe(expectedInlineStyleHashes + 1) // Inlined style
expect(externalStyleHashes).toBe(expectedExternalStyleHashes)
})


it('sets script-src for external scripts', async () => {
const res = await fetch('/external-script')
Expand Down

0 comments on commit 1dd0496

Please sign in to comment.