Skip to content

Angular service worker does not pick up changes in CSP headers #35491

Closed

Description

@pleinonen

🐞 bug report

Affected Package

The issue is caused by package @angular/pwa

Is this a regression?

No

Description

Following exception can be seen in console:

Refused to connect to 'https://www.googletagmanager.com/gtag/js?id=XYZ' because it violates the following Content Security Policy directive: "connect-src 'self' [OMITTED]

Problem is that connect-src statement is old and should have been replaced by new one. Looking at the network log I can see the that CSP is properly set:
content-security-policy: report-uri /csp_error; default-src 'self'; connect-src 'self' [OMITTED] https://www.googletagmanager.com; script-src 'self' 'unsafe-eval' [OMITTED]; img-src 'self' [OMITTED]; font-src 'self' [OMITTED]; style-src 'self' 'unsafe-inline' [OMITTED]; frame-src 'self' *

Further proof that service worker is a culprit is that problem cannot be produced when browser cache is cleared or worker disabled. Another way to fix issue is to temporarily load safety-worker.js to uninstall the worker.

🔬 Minimal Reproduction

  • Enable CSP to a site with service worker and populate script-scr and connect-scr fields
  • Access site to install sw with old CSP headers.
  • Add <script> reference to https://www.googletagmanager.com/gtag/js and add https://www.googletagmanager.com to content-security-policy script-scr and connect-scr fields.
  • Access site again and wait for sw to update app in background. After reloading, error should be visible in console.

🔥 Exception or Error


ngsw-worker.js:2726 Refused to connect to 'https://www.googletagmanager.com/gtag/js?id=XYZ' because it violates the following Content Security Policy directive: "connect-src 'self' [OMITTED & OUTDATED]".

(anonymous) @ ngsw-worker.js:2726
(anonymous) @ ngsw-worker.js:1804
(anonymous) @ ngsw-worker.js:1800
safeFetch @ ngsw-worker.js:2724
(anonymous) @ ngsw-worker.js:2176
fulfilled @ ngsw-worker.js:1801
Promise.then (async)
step @ ngsw-worker.js:1803
fulfilled @ ngsw-worker.js:1801
Promise.then (async)
step @ ngsw-worker.js:1803
fulfilled @ ngsw-worker.js:1801
Promise.then (async)
step @ ngsw-worker.js:1803
(anonymous) @ ngsw-worker.js:1804
(anonymous) @ ngsw-worker.js:1800
handleFetch @ ngsw-worker.js:2131
onFetch @ ngsw-worker.js:1977
(anonymous) @ ngsw-worker.js:1911
ngsw-worker.js:2726 Refused to connect to 'https://www.googletagmanager.com/gtag/js?id=XYZ' because it violates the document's Content Security Policy.

🌍 Your Environment

Angular Version:


Angular CLI: 8.3.23
Node: 10.15.3
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router, service-worker

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.23
@angular-devkit/build-angular     0.803.23
@angular-devkit/build-optimizer   0.803.23
@angular-devkit/build-webpack     0.803.23
@angular-devkit/core              8.3.23
@angular-devkit/schematics        8.3.23
@angular/cdk                      8.2.3
@angular/cli                      8.3.23
@angular/pwa                      0.803.23
@ngtools/webpack                  8.3.23
@schematics/angular               8.3.23
@schematics/update                0.803.23
rxjs                              6.5.4
typescript                        3.5.3
webpack                           4.39.2

Error can be reproduced with latest FireFox and Chrome browsers. Tag manager script is loaded runtime (id depends on deployment environment).

Activity

  1. added this to the needsTriage milestone on Feb 17, 2020
  2. gkalpak commented on Feb 19, 2020

    @gkalpak
    Member

    It is not 100% clear to me what the issue is (or how to reproduce), but it sounds like this could be
    related to how browsers in general handle requests from ServiceWorkers (in the presense of a CSP) - not specific to Angular). You can read more about the problem (and how to fix it) here.

    If my suspicion is correct, this issue is essentially a duplicate of #31330 (see there for some more resources).

    @pleinonen, can you confirm whether setting the correct CSP headers for the ServiceWorker script (typically ngsw-worker.js) fixes the issue?

  3. pleinonen commented on Feb 19, 2020

    @pleinonen
    Author

    I already addressed the linked issue by adding domain 'https://www.googletagmanager.com' to both script-src and connect-src policies. Latter is required by service worker as described in linked article. Once domain is white listed in connect-src, service worker has no problem connecting to it.

    Problem is that service worker does not pick up the updated connect-src policy during application update. Only way to force this update in production is to serve safety-worker, as far as I know. Locally you can check the 'Update on reload' checkbox in Chrome DevTools, this is also another proof that connect-src is properly set.

    Suggested workaround does not help as updated 'connect-src *' is not picked up either - it does not matter what the updated connect-src contains if service workers fails to detect the update in the first place.

    @gkalpak I can confirm that correct CSP headers are set for ngsw-worker.js but service worker fails to detect the updated policy unless forcibly reinstalled.

  4. gkalpak commented on Feb 24, 2020

    @gkalpak
    Member

    I see. So, if I understand the problem correctly, it is that the browser does not pick up the updated CSP headers for the SW script itself. This sounds like a browser issue (not specific to Angular).

    According to the SW update algorithm from the spec, browsers do a byte-for-byte comparison of the SW script response's body (i.e. ignore headers). I'm afraid there is not much we can do on the Angular side.

    Consider reporting this to https://github.com/w3c/ServiceWorker (if it is not reported already).
    w3c/ServiceWorker#755 seems relevant (although not exactly the same issue).

    Closing this, because I don't think this is something that can be fixed in Angular.

  5. angular-automatic-lock-bot commented on Mar 26, 2020

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  6. locked and limited conversation to collaborators on Mar 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: service-workerIssues related to the @angular/service-worker package

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions