mirror of
https://github.com/vitejs/vite.git
synced 2024-11-21 22:59:10 +00:00
fix(cspNonce): don't overwrite existing nonce values (#16415)
This commit is contained in:
parent
6cccef78a5
commit
b8726357c9
@ -1180,24 +1180,29 @@ export function injectNonceAttributeTagHook(
|
||||
return
|
||||
}
|
||||
|
||||
const { nodeName, attrs, sourceCodeLocation } = node
|
||||
|
||||
if (
|
||||
node.nodeName === 'script' ||
|
||||
(node.nodeName === 'link' &&
|
||||
node.attrs.some(
|
||||
nodeName === 'script' ||
|
||||
(nodeName === 'link' &&
|
||||
attrs.some(
|
||||
(attr) =>
|
||||
attr.name === 'rel' &&
|
||||
parseRelAttr(attr.value).some((a) => processRelType.has(a)),
|
||||
))
|
||||
) {
|
||||
// If we already have a nonce attribute, we don't need to add another one
|
||||
if (attrs.some(({ name }) => name === 'nonce')) {
|
||||
return
|
||||
}
|
||||
|
||||
const startTagEndOffset = sourceCodeLocation!.startTag!.endOffset
|
||||
|
||||
// if the closing of the start tag includes a `/`, the offset should be 2 so the nonce
|
||||
// is appended prior to the `/`
|
||||
const appendOffset =
|
||||
html[node.sourceCodeLocation!.startTag!.endOffset - 2] === '/' ? 2 : 1
|
||||
const appendOffset = html[startTagEndOffset - 2] === '/' ? 2 : 1
|
||||
|
||||
s.appendRight(
|
||||
node.sourceCodeLocation!.startTag!.endOffset - appendOffset,
|
||||
` nonce="${nonce}"`,
|
||||
)
|
||||
s.appendRight(startTagEndOffset - appendOffset, ` nonce="${nonce}"`)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -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('')
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user