Reputation: 6440
The Angular docs mention CSP, and Google's Security Engineers recommend against using whitelists. What I haven't figured out yet is how to inject a nonce into the script tag(s) that Angular injects into the index.html (to "bootstrap" itself). I suppose it has to do with Webpack, but the ng eject
command has been removed from the cli a while ago, I believe, and I haven't been able to find a tutorial on this. Can anyone get me started with pointers, please?
The Webpack docs mention that a variable
__webpack_nonce__ = 'let-nonce-string-be-injected-by-server-here';
needs to be defied in the entry file (not the config - so an @angular-builders/custom-webpack npm module is probably not going to help?), but I'm not clear what Webpack's entry file is in the context of Angular...?
P.S.: Judging from this blog post, the polyfill file is one of the entry files - but it looks like it's not the first, so I doubt adding the variable there will work...?
Upvotes: 5
Views: 11947
Reputation: 1991
If you are using Angular version less than 19, it will be ugly but it IS possible. Suppose you have a <meta>
tag (within your document <head>
) like this:
<head>
...
<meta http-equiv="Content-Security-Policy" content="script-src 'strict-dynamic' 'nonce-rAnd0m' 'sha384-cw8QV0pYMDtz3Y6/mkyvB6TUzqZpq4rQD8j1sD/Y0wYSv7c10jG4qr8Y5F8vpuAb';">
...
</head>
You need to add a <script>
tag IMMEDIATELY after <app-root>
, which will inject a newly-generated (or server-generated) nonce using a regular expression replacement. Here is a script for injecting a 32-character nonce generated by the Crypto
interface's method randomUUID()
(link to MDN page):
<app-root></app-root>
<script nonce="rAnd0m">
var random = (self.crypto.randomUUID() + self.crypto.randomUUID()).replace(/-/g, '').substr(0, 32); // or use server-generated random string
var meta = document.querySelectorAll("meta[http-equiv]")[0];
var csp = meta.getAttribute("content");
meta.setAttribute("content", csp.replace(/\'nonce-/, "'nonce-" + random + "' 'nonce-"));
</script>
Upvotes: 0