pusher / push-notifications-web

Beams Browser notifications
MIT License
39 stars 19 forks source link

Pusher fails to initialise without unsafe CSP rule `script-src: "'unsafe-eval'"` #127

Closed wjpg closed 1 year ago

wjpg commented 1 year ago

When using CSP headers - without "'unsafe-eval'" being permitted, push-notifications-web fails to initialise the client. Errors with more detail below. Note. We are already permitting "https://js.pusher.com/beams/service-worker.js" within a "script-src" value.

v 1.1.0 FIREFOX

EvalError: call to Function() blocked by CSP
    u push-notifications-esm.js:759
    48719 push-notifications-esm.js:32

Content Security Policy: The page's settings blocked the loading of a resource at eval ("script-src")

It is hitting the accidentalStrictMode catch which I think is coming from regeneratorRuntime, within push-notifications-esm.js

CHROME

Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'https://js.pusher.com/beams/service-worker.js' failed to load.

Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('https://our-url.com') with script ('https://our-url.com/service-worker.js?pusherBeamsWebSDKVersion=1.1.0'): ServiceWorker script evaluation failed

V 2.0.0-beta.2 CHROME:

Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('https://our-url.com') with script ('https://our-url.com/service-worker.js?pusherBeamsWebSDKVersion=2.0.0-beta.2'): ServiceWorker script evaluation failed

FIREFOX:

Uncaught (in promise) TypeError: ServiceWorker script at https://our-url.com/service-worker.js?pusherBeamsWebSDKVersion=2.0.0-beta.2 for scope https://our-url.com/ threw an exception during script evaluation. 
wjpg commented 1 year ago

Just to establish what I uncovered in my investigation:

There's an extensive write up of this issue here: https://github.com/facebook/regenerator/issues/378.

The problematic code block exists in service-worker.js, push-notifications-cdn.js & push-notifications-esm.js. It is from the 'regenerator-runtime' package, though in the pusher SDK I think it comes from the use of the babel '@babel/plugin-transform-runtime' plugin here: https://github.com/pusher/push-notifications-web/blob/master/rollup/esm.js#L20 https://github.com/pusher/push-notifications-web/blob/master/rollup/service-worker.js#L21 https://github.com/pusher/push-notifications-web/blob/master/rollup/cdn.js#L21

It appears there was a fix released in a more recent regenerator-runtime version. tried forcing resolutions across @babel/runtime, @babel/plugin-transform-runtime & regenerator-runtime but that didn't have an impact

Updating to 2.0.0-beta.2 and adding globalThis.regeneratorRuntime = undefined to service-worker.js solved the issue. I presume 2.0.0-beta.2 brought with it the updated regenerator-runtime package which includes this fix https://github.com/facebook/regenerator/pull/480/files#diff-798a682df82030e703dee15a6f36614fe31c1206bae21a66bbb6064d519e2981L736-R753

I was unable to find a solution on the current stable version 1.1.0