From my understanding of Content Security Policy, the nonce has to change on every request. That means (I think) it must be generated at run-time on the client, not at build-time in the Webpack config. I've tested the webpack_nonce functionality in my app and it works great.
Unfortunately, I'm not sure how to get that value, generated at run-time on the client, to the actual CSP policy, which is either set as a meta-tag in the index.html file (or some equivalent) or on the server itself.
I suppose you could set the CSP meta-tag dynamically on the client, but that seems like a security risk. I've experimented with the csp-webpack-plugin, which calculates hashes of files at build-time and then adds them to the index.html. This process makes sense to me, it just didn't support our use case.
I just feel like I'm missing something with using webpack_nonce.
We were able to get a dynamic nonce by having webpack build our index page (e.g via HtmlWebpackPlugin) as a template then serving it dynamically. This way, you can set
__webpack_nonce__
to an interpolation expression like<%=nonce%>
and the server view engine can sub in your dynamic nonce at page-load time. For example, if you're using express:Webpack config:
Webpack entry point (index.js):
Express app:
The injected
<script>
tags will have the literal attributenonce=<%=nonce%>
appended, which the server will then interpolate when serving your page.Note that if you use a custom template with HtmlWebpackPlugin, you might want to set a different interpolation delimiter for
ejs
otherwise Webpack will interpolate the nonce expression at build time instead of runtime.Express app: