Skip to content

Commit 8df91b8

Browse files
committed
feat(ssr): add csp nonce to all elements
add csp nonce to all elements that could potentiall be affected by CSP directives
1 parent 8d3fce0 commit 8df91b8

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

src/server/template-renderer/index.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default class TemplateRenderer {
5555
this.inject = options.inject !== false
5656
// if no template option is provided, the renderer is created
5757
// as a utility object for rendering assets like preload links and scripts.
58-
58+
5959
const { template } = options
6060
this.parsedTemplate = template
6161
? typeof template === 'string'
@@ -133,7 +133,7 @@ export default class TemplateRenderer {
133133
return (
134134
// render links for css files
135135
(cssFiles.length
136-
? cssFiles.map(({ file }) => `<link rel="stylesheet" href="${this.publicPath}${file}">`).join('')
136+
? cssFiles.map(({ file }) => `<link rel="stylesheet" href="${this.publicPath}${file}"${getNonceAttribute(context)}>`).join('')
137137
: '') +
138138
// context.styles is a getter exposed by vue-style-loader which contains
139139
// the inline component styles collected during SSR
@@ -177,7 +177,7 @@ export default class TemplateRenderer {
177177
asType !== '' ? ` as="${asType}"` : ''
178178
}${
179179
extra
180-
}>`
180+
}${getNonceAttribute(context)}>`
181181
}).join('')
182182
} else {
183183
return ''
@@ -198,7 +198,7 @@ export default class TemplateRenderer {
198198
if (alreadyRendered(file)) {
199199
return ''
200200
}
201-
return `<link rel="prefetch" href="${this.publicPath}${file}">`
201+
return `<link rel="prefetch" href="${this.publicPath}${file}"${getNonceAttribute(context)}>`
202202
}).join('')
203203
} else {
204204
return ''
@@ -214,9 +214,8 @@ export default class TemplateRenderer {
214214
const autoRemove = process.env.NODE_ENV === 'production'
215215
? ';(function(){var s;(s=document.currentScript||document.scripts[document.scripts.length-1]).parentNode.removeChild(s);}());'
216216
: ''
217-
const nonceAttr = context.nonce ? ` nonce="${context.nonce}"` : ''
218217
return context[contextKey]
219-
? `<script${nonceAttr}>window.${windowKey}=${state}${autoRemove}</script>`
218+
? `<script${getNonceAttribute(context)}>window.${windowKey}=${state}${autoRemove}</script>`
220219
: ''
221220
}
222221

@@ -226,7 +225,7 @@ export default class TemplateRenderer {
226225
const async = (this.getUsedAsyncFiles(context) || []).filter(({ file }) => isJS(file))
227226
const needed = [initial[0]].concat(async, initial.slice(1))
228227
return needed.map(({ file }) => {
229-
return `<script src="${this.publicPath}${file}" defer></script>`
228+
return `<script src="${this.publicPath}${file}" defer${getNonceAttribute(context)}></script>`
230229
}).join('')
231230
} else {
232231
return ''
@@ -275,3 +274,7 @@ function getPreloadType (ext: string): string {
275274
return ''
276275
}
277276
}
277+
278+
function getNonceAttribute(context: Object): string {
279+
return context.nonce ? ` nonce="${context.nonce}"` : ''
280+
}

0 commit comments

Comments
 (0)