React Content Security Policy with nonce
How to add CSP nonce to React + Webpack app with Node and Nginx

The main crux of the nonce is that: nonces must be regenerated for every page request and they must be unguessable.
The nonce attribute in the script lets you “whitelist” inline script and style elements, eliminating the need for the broader and less secure CSP unsafe-inline directive, thereby maintaining the fundamental CSP feature of prohibiting inline script and style elements in general.
Utilising the nonce attribute in script or style informs browsers that the inline content was deliberately included in the document by the server (nginx) rather than being injected by a potentially malicious third party.
The Content Security Policy article’s If you absolutely must use it section has a good example of how to use the nonce attribute in the script or style:
The react application is built using webpack, in the webpack config the NonceInjector Plugin is used to put a placeholder (_NONCE_) for the attribute nonce in script and style HTML tags.
<script
defer="defer"
src="/static/js/main.0405c3f1.js"
nonce="_NONCE_"
></script>
<link href="/static/css/main.f855e6bc.css" rel="stylesheet" nonce="_NONCE_" />
Nonce Injector Webpack Plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
class NonceInjector {
constructor(NONCE_PLACEHOLDER) {
this.NONCE_PLACEHOLDER = NONCE_PLACEHOLDER;
}
apply(compiler) {
compiler.hooks.thisCompilation.tap("NonceInjector", (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).afterTemplateExecution.tapAsync(
"NonceInjector",
(compilation, callback) => {
const { headTags } = compilation;
headTags.forEach((tag) => {
tag.attributes.nonce = this.NONCE_PLACEHOLDER;
});
callback(null, compilation);
}
);
});
}
}
module.exports = NonceInjector;
To verify the CSP nonce being changed in every request, need a server client setup and its done using docker.
I have done 2 implementations here, one with Nodejs and another with Nginx
Express.js (Node server)
Express.js Node app serves the build app and replaces the nonce placeholder with the generated nonce on each request.
Github Code: Expressjs Server Sample project
Node use Buffer and Crypto to generate the random nonce in the server file
Nginx Server
Nginx serves the build react app and replaces the nonce placeholder with the generated nonce on each request.
Github Code: Nginx Server Sample project
Nginx utilise the njs scripting to generate the random nonce string. Nginx Config file
Verify CSP Header
You can inspect each request and see the Content-Security-Policy added to the response headers with nonce
Here in the response each script and style tag will have the same nonce added to attributes.

Verify Nonce in script and style

If you already have a react - webpack app serving with either Node or Nginx you can utilise above NonceInjector Plugin and this setup to implement the CSP nonce.
Cheers ✌️