Skip to content

Commit

Permalink
fix(cspNonce): don't overwrite existing nonce values
Browse files Browse the repository at this point in the history
Fixes: #16414
  • Loading branch information
thebanjomatic committed Apr 13, 2024
1 parent 6c323d5 commit 76b0efb
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
7 changes: 7 additions & 0 deletions packages/vite/src/node/plugins/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,13 @@ export function injectNonceAttributeTagHook(
parseRelAttr(attr.value).some((a) => processRelType.has(a)),
))
) {
const alreadyContainsNonce = node.attrs.some(
({ name }) => name === 'nonce',
)
if (alreadyContainsNonce) {
return
}

// if the closing of the start tag includes a `/`, the offset should be 2 so the nonce
// is appended prior to the `/`
const appendOffset =
Expand Down
14 changes: 14 additions & 0 deletions playground/csp/__tests__/csp.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ test('dynamic js', async () => {
)
})

test('inline js', async () => {
await expectWithRetry(() => page.textContent('.inline-js')).toBe(
'inline-js: ok',
)
})

test('nonce attributes are not repeated', async () => {
const htmlSource = await page.content()
expect(htmlSource).not.toContain(/nonce=""[^>]*nonce=""/)
await expectWithRetry(() => page.textContent('.double-nonce-js')).toBe(
'double-nonce-js: ok',
)
})

test('meta[property=csp-nonce] is injected', async () => {
const meta = await page.$('meta[property=csp-nonce]')
expect(await (await meta.getProperty('nonce')).jsonValue()).not.toBe('')
Expand Down
10 changes: 10 additions & 0 deletions playground/csp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@
<p class="dynamic">dynamic</p>
<p class="js">js: error</p>
<p class="dynamic-js">dynamic-js: error</p>
<p class="inline-js">inline-js: error</p>
<p class="double-nonce-js">double-nonce-js: error</p>
<script>
document.querySelector('.inline-js').textContent = 'inline-js: ok'
</script>
<script nonce="#$NONCE$#">
// this test case is to ensure that the nonce isn't being
// double-applied if an existing attribute is present.
document.querySelector('.double-nonce-js').textContent = 'double-nonce-js: ok'
</script>

0 comments on commit 76b0efb

Please sign in to comment.