fix(vue-renderer): add the csp hash if unsafe-inline hasn't been specified (#5387)

This commit is contained in:
Sam Bowler 2019-03-29 16:09:53 +00:00 committed by Pooya Parsa
parent 91f4eb0468
commit 97db6a4b41
2 changed files with 56 additions and 1 deletions

View File

@ -408,7 +408,11 @@ export default class VueRenderer {
// Calculate CSP hashes // Calculate CSP hashes
const cspScriptSrcHashes = [] const cspScriptSrcHashes = []
if (this.context.options.render.csp) { const csp = this.context.options.render.csp
const containsUnsafeInlineScriptSrc = csp && csp.policies && csp.policies['script-src'] && csp.policies['script-src'].includes(`'unsafe-inline'`)
// Only add the hash if 'unsafe-inline' rule isn't present to avoid conflicts (#5387)
if (csp && !containsUnsafeInlineScriptSrc) {
const { hashAlgorithm } = this.context.options.render.csp const { hashAlgorithm } = this.context.options.render.csp
const hash = crypto.createHash(hashAlgorithm) const hash = crypto.createHash(hashAlgorithm)
hash.update(serializedSession) hash.update(serializedSession)

View File

@ -171,6 +171,31 @@ describe('basic ssr csp', () => {
expect(uniqueHashes.length).toBe(hashes.length) expect(uniqueHashes.length).toBe(hashes.length)
} }
) )
test(
'Not contain hash when \'unsafe-inline\' option is present in script-src policy',
async () => {
const policies = {
'script-src': [`'unsafe-inline'`]
}
nuxt = await startCspServer({
policies
})
for (let i = 0; i < 5; i++) {
await rp(url('/stateless'), {
resolveWithFullResponse: true
})
}
const { headers } = await rp(url('/stateful'), {
resolveWithFullResponse: true
})
expect(headers[cspHeader]).toMatch(/script-src 'self' 'unsafe-inline'$/)
}
)
}) })
describe('debug mode', () => { describe('debug mode', () => {
test( test(
@ -314,6 +339,7 @@ describe('basic ssr csp', () => {
expect(uniqueHashes.length).toBe(hashes.length) expect(uniqueHashes.length).toBe(hashes.length)
} }
) )
test( test(
'Not contain old hashes when loading new page', 'Not contain old hashes when loading new page',
async () => { async () => {
@ -339,5 +365,30 @@ describe('basic ssr csp', () => {
expect(intersection.size).toBe(0) expect(intersection.size).toBe(0)
} }
) )
test(
'Not contain hash when \'unsafe-inline\' option is present in script-src policy',
async () => {
const policies = {
'script-src': [`'unsafe-inline'`]
}
nuxt = await startCspDevServer({
policies
})
for (let i = 0; i < 5; i++) {
await rp(url('/stateless'), {
resolveWithFullResponse: true
})
}
const { headers } = await rp(url('/stateful'), {
resolveWithFullResponse: true
})
expect(headers[reportOnlyHeader]).toMatch(/script-src 'self' 'unsafe-inline'$/)
}
)
}) })
}) })