Following the Angular security guide I'm attempting to use CSP in my Angular application but I'm having difficulties with two parts.
First any styles included via the angular.json
configuration file seem to become inlined when running ng build
. Second, any link
tags that import styles also seem to be loaded and inlined by ng-build
.
For example. I have this section in my angular.json
file:
"styles": [
"src/styles.scss"
]
And the following <link>
in my index.html:
<link href="//fonts.googleapis.com/css2?family=Montserrat&family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;0,800;1,300;1,400;1,600;1,700;1,800&display=swap" rel="stylesheet">
After running ng build
the index.html
file becomes this:
<!DOCTYPE html>
<html lang="en">
<head><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<meta charset="utf-8">
<title>Site</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- TODO: REPLACE BY ACTUAL HTTP HEADER (AND ACTUAL NONCE) -->
<script>
myRandomNonceValue = 'randomNonceGoesHere';
</script>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' fonts.googleapis.com 'nonce-randomNonceGoesHere'; script-src 'self' 'nonce-randomNonceGoesHere'; font-src https://fonts.gstatic.com data:;">
<style type="text/css">
<!-- Content from fonts.googleapis.com is added here -->
</style>
<link rel="icon" type="image/x-icon" href="favicon.ico">
<style>
<!-- Content from styles.scss is added here -->
</style>
<link rel="stylesheet" href="styles.dd15db77dac66d40.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.dd15db77dac66d40.css"></noscript></head>
<body>
<app-root></app-root>
<script src="runtime.02ee8844f7593507.js" type="module"></script><script src="polyfills.57c3a9c9c943caee.js" type="module"></script><script src="main.9eaed3d82b050a64.js" type="module"></script>
</body></html>
At runtime this results in the browser complaining about the inline style-elements not having the csp-nonce added to them. The styles for the components is added correctly using the nonce, but these inline ones aren't.
The only way I got this to work is to allow unsafe, but that pretty much removes the whole nonce-usefulness.
It seems like I'm missing something as this should just work right? How can I make Angular not inline these <style>
tags but instead just make it download them?