Angular 18.2 with strict CSP (nonces) is not injecting the ngCspMedia script into index.html

Discussão em 'Angular' iniciado por JackDogStar, Dezembro 31, 2024.

  1. JackDogStar

    JackDogStar Guest

    I have an Angular v. 18.2 app. It uses nonces for strict Content-Security-Policy. It is built and deployed in Jenkins. It was working fine until about a few weeks ago (not sure of the exact date of failure). In out package.json file we have a number of packages that use caret minor version and update enabled. (i.e: "^18.2.0).

    When we build and deploy via Jenkins, we get an error regarding content-security-policy. Here is the error:

    [our server].com/:67 "Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-PhZhJf6yjkLGyqjMeaTcmA==' 'unsafe-hashes'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution."


    Each of the following is true:

    1. The error occurs when we build using Jenkins.
    2. The error occurs on previous versions when those versions of our app that are built via Jenkins. These version used to work.
    3. This is important!: The error does **NOT **occur if we build manually in Visual Studio and then manually install the UI onto the server.
    4. The error does NOT occur if we run in Visual Studio.
    5. At this point, the error occurs regardless of whether I use ‘unsafe-hashes’ in the script CSP. I am still experimenting with this.

    The problem appears to be that the build process cannot detect strict CSP and so is not injection the ngCspMedia script into the index.html and make necessary changes to <link> elements. If I build in Visual Studio and then copy the script from the /dist/index.html file to the index.html file on my deployment server, it works. But simply trying to implement the script by hard coding it into my index.html file before build does not work.

    Here is the script that should be injected into index.html, but is not:

    (() => {
    const CSP_MEDIA_ATTR = 'ngCspMedia';
    const documentElement = document.documentElement;
    const listener = (e) => {
    const target = e.target;
    if (!target || target.tagName !== 'LINK' || !target.hasAttribute(CSP_MEDIA_ATTR)) {
    return;
    }
    target.media = target.getAttribute(CSP_MEDIA_ATTR);
    target.removeAttribute(CSP_MEDIA_ATTR);
    if (!document.head.querySelector(`link[${CSP_MEDIA_ATTR}]`)) {
    documentElement.removeEventListener('load', listener);
    }
    };
    documentElement.addEventListener('load', listener, true);
    })();


    I have made sure that Jenkins was building using 18.2 CLI. In Visual Studio, in a Powershell, I ran 'ng build' and then examined the index.html file in the /dist/ directory. It had successfully injected the ngCspMedia script. I have tried using a strict CSP in the index.html header to make sure the CLI could detect it. (I used this: <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-{nonce}'; style-src 'self' 'nonce-{nonce}';">) I also used the CSP that has more policies but that used to work.

    EDIT: If I turn off style optimizations, the page will load (though I do not get the ngCspMedia script. Here is what I mean, from the angular.json file:

    "baseHref": "/[obfuscate]/",
    "optimization": {
    "scripts": true,
    "styles": false
    },
    "outputHashing": "all",
    "sourceMap": false,
    "namedChunks": false,
    "aot": true,
    "extractLicenses": true,
    "vendorChunk": false,
    "buildOptimizer": true,
    "fileReplacements": [

    Continue reading...

Compartilhe esta Página