-
Notifications
You must be signed in to change notification settings - Fork 27k
Description
Command
build
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
No response
Description
I wanted to add Content-Security-Policy to my app and found that the CSP_NONCE token way to implement it looked to be the easiest with SSR.
The nonce is generated in the express route handler and provided to the app with the REQUEST_CONTEXT and TransferState.
Every angular script and style is correctly appended with that nonce, just the "ng-event-dispatch-contract" script is missing the nonce.
I want to generate the nonce myself because the app uses a few custom scripts at runtime that require the nonce
Minimal Reproduction
- Create app with SSR enabled
- Set route to RenderMode.Server
- Add (click) handler to any component (required or else the script gets removed before send)
- Add CSP nonce token to client and server (just to replicate the current project, I think it should also work only server side)
function provideCSPNonce() {
return {
provide: CSP_NONCE,
deps: [TransferState, REQUEST_CONTEXT],
useFactory: (transferState: TransferState, rq : any)=>{
if(!!rq){
const nonce = rq.nonce;
transferState.set(CSP_NONCE_TRANSFER, nonce);
return nonce
}else{
return transferState.get(CSP_NONCE_TRANSFER, null);
}
}
}
}- Add CSP and nonce to headers and request context:
/**
* Handle all other requests by rendering the Angular application.
*/
app.use(async (req, res, next) => {
const resp = await angularApp.handle(req, {
nonce: 'test123'
})
if(!resp)
return next();
resp.headers.set("Content-Security-Policy", `default-src 'self'; script-src 'self' 'nonce-${'test123'}';`);
await writeResponseToNodeResponse(resp, res);
});Exception or Error
The browser will complain, that the ng-event-dispatch-contract script does not have a nonce:
Executing inline script violates the following Content Security Policy directive 'script-src 'self' 'nonce-test123''. Either the 'unsafe-inline' keyword, a hash ('sha256-VM2mZqyEQZoLzoTrp5EigFvzQ0+f1wSeBuoOn95WHCg='), or a nonce ('nonce-...') is required to enable inline execution. The action has been blocked.
Your Environment
Angular CLI: 20.3.14
Node: 24.9.0
Package Manager: npm 11.6.0
OS: darwin arm64
Angular: 20.3.16
... common, compiler, compiler-cli, core, forms
... platform-browser, platform-server, router
Package Version
------------------------------------
@angular-devkit/architect 0.2003.14
@angular-devkit/core 20.3.14
@angular-devkit/schematics 20.3.14
@angular/build 20.3.14
@angular/cli 20.3.14
@angular/ssr 20.3.14
@schematics/angular 20.3.14
rxjs 7.8.2
typescript 5.9.3
Anything else relevant?
During creation of a reproduction project, I also noticed, that prerendered routes also do not work with just the CSP token method.
I think the token method is incompatible with the current SSR workflow.
This should probably be documented in the security docs