From 5ebf60f2a144e1ec888a1308ae0739377cdcd14c Mon Sep 17 00:00:00 2001 From: Kouki Narumi Date: Wed, 17 Jan 2018 00:10:10 +0900 Subject: [PATCH] feat: external script support for CSP (#2608) --- lib/common/options.js | 4 +++- lib/core/middleware/nuxt.js | 5 +++-- lib/core/renderer.js | 2 +- test/basic.ssr.test.js | 7 ++++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/common/options.js b/lib/common/options.js index 825f19079d..20c5c98ca9 100755 --- a/lib/common/options.js +++ b/lib/common/options.js @@ -305,7 +305,9 @@ Options.defaults = { etag: { weak: false }, - csp: undefined + csp: { + allowedSouces: [] + } }, watchers: { webpack: { diff --git a/lib/core/middleware/nuxt.js b/lib/core/middleware/nuxt.js index c21da5194c..de6152046b 100644 --- a/lib/core/middleware/nuxt.js +++ b/lib/core/middleware/nuxt.js @@ -67,10 +67,11 @@ module.exports = async function nuxtMiddleware(req, res, next) { res.setHeader('Link', pushAssets.join(',')) } - if (this.options.render.csp) { + if (this.options.render.csp.hashAlgorithm) { + let allowedSources = cspScriptSrcHashes.concat(this.options.render.csp.allowedSources) res.setHeader( 'Content-Security-Policy', - `script-src 'self' ${(cspScriptSrcHashes || []).join(' ')}` + `script-src 'self' ${(allowedSources || []).join(' ')}` ) } diff --git a/lib/core/renderer.js b/lib/core/renderer.js index db6e66a10f..7d6e9a547b 100644 --- a/lib/core/renderer.js +++ b/lib/core/renderer.js @@ -361,7 +361,7 @@ module.exports = class Renderer { isJSON: true })};` let cspScriptSrcHashes = [] - if (this.options.render.csp) { + if (this.options.render.csp.hashAlgorithm) { let hash = crypto.createHash(this.options.render.csp.hashAlgorithm) hash.update(serializedSession) cspScriptSrcHashes.push( diff --git a/test/basic.ssr.test.js b/test/basic.ssr.test.js index 26e7cf107e..0310c03882 100755 --- a/test/basic.ssr.test.js +++ b/test/basic.ssr.test.js @@ -24,7 +24,10 @@ test.serial('Init Nuxt.js', async t => { stats: false }, render: { - csp: true + csp: { + hashAlgorithm: 'sha256', + allowedSources: ['https://example.com', 'https://example.io'] + } } } @@ -256,6 +259,8 @@ test('Content-Security-Policy Header', async t => { }) // Verify functionality t.regex(headers['content-security-policy'], /script-src 'self' 'sha256-.*'/) + t.true(headers['content-security-policy'].includes('https://example.com')) + t.true(headers['content-security-policy'].includes('https://example.io')) }) test('/_nuxt/server-bundle.json should return 404', async t => {