Repository navigation
Description
🐞 bug report
Affected Package
The issue is caused by package @angular/pwaIs this a regression?
NoDescription
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
gkalpak commentedon Feb 19, 2020
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?pleinonen commentedon Feb 19, 2020
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.jsbut service worker fails to detect the updated policy unless forcibly reinstalled.gkalpak commentedon Feb 24, 2020
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.
angular-automatic-lock-bot commentedon Mar 26, 2020
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.