Enabling Hash-Based Content Security Policy in Angular

How to Enhance App Security with CSP Strict Dynamic Hashing

Ensuring security is a fundamental requirement for modern web applications, and one of the biggest threats we still face is Cross-site scripting (XSS). As a quick reminder, this type of attack happens when malicious JavaScript code is injected into a trusted website and run in a user’s browser, triggering unauthorized actions or potentially resulting in data leaks.

The W3C security standard named Content Security Policy (CSP) was introduced over a decade ago as a protective measure against XSS attacks and is currently evolving through its Level 3 Working Draft.

A widely recommended strategy to adopt is the Hash-based Strict CSP that safeguards the integrity of inline scripts by requiring the browser to match their content against a hash value located in the HTTP Content-Security-Policy response header. This prevents unauthorized or malicious scripts from executing, as their hashes won’t match.

In the latest Angular version, the framework now automatically handles hash generation for inline scripts, making it much easier to enforce strict CSP rules without requiring developers to manually configure policies and generate hashes with cryptographic utils at build time on our own.

How Angular implements hash-based CSP

Angular has supported CSP features for years. Angular 16 introduced nonce-based CSP for inline styles so developers could use the ngCspNonce attribute or the CSP_NONCE injection token to manage style declarations, as they can also be exploited in XSS attacks through unauthorized modifications, CSS keylogging, or external stylesheet injection.

Angular 19 recently introduced automatic hash-based CSP as a Developer Preview, simplifying the protection of applications against XSS vulnerabilities.

To enable this feature, let’s head to the angular.json file and set the new autoCSP property:

{
“projects”: {
“<app>”: {
“architect”: {
“build”: {
“options”: {
“security”: {
“autoCSP”: true
}

}

When this feature enabled, the Angular builder computes a SHA-256 hash for all inline scripts based on their file contents and declares this information in the CSP meta tag to ensure only the original scripts can run. Unauthorized or modified scripts cannot execute, as the browser validates all the scripts against the CSP policy details.

Instead of directly declaring JavaScript sources in the <script> element, Angular exposes an inline script logic to manage script loading, leveraging the strict-dynamic CSP rule so additional scripts don’t need individual hashes.

Traditionally, the Angular-generated index.html file has directly declared JavaScript sources in <script> elements, which could make them vulnerable to unauthorized execution if an attacker gains control over the file’s content. Here’s an example prior to enabling the new CSP mechanism:

https://medium.com/media/c224d5cf98964b6a6b3da23c5dfbf925/href

Strict hash-based CSP rules mitigate this risk by executing only the original scripts. After enabling autoCSP in the Angular configuration file, the index.html file looks like this:

https://medium.com/media/5122fcdf5ab825531bdcecc926272da8/href

It’s worth mentioning that turning off the autoCSP rule in development mode can be useful for debugging. Since this feature is primarily intended for production, where security is a priority, it’s optional during development. Once it moves out of the Developer Preview phase, it’s expected to be enabled by default in production configurations.

Outro

To wrap up, turning on automatic strict hash-based CSP in the Angular configuration file is an excellent way to add another layer of security to our web apps. Allowing the framework to generate trusted inline scripts for us makes CSP compliance straightforward.

What other steps can we take to continue improving our Angular app’s security these days?

Lee la versión en español de este artículo en el blog de ng-conf:

Habilitando reglas del estándar de seguridad web CSP en Angular

Enabling Hash-Based Content Security Policy in Angular was originally published in ngconf on Medium, where people are continuing the conversation by highlighting and responding to this story.

Leave a Comment

Your email address will not be published. Required fields are marked *