Webpushr and content security policy

I’m trying to get Webpushr to work but I keep running into our content security policy that does not allow inline scripts. It seems that Webpushr is trying to create an inline script but I cannot find anything about how to implement Webpushr with a content security policy in place. Does anybody have any experience with this?

Regards,
Wietse

Hi,

Can you please share you website URL, so that I can check?

Hi Webpushr support,

Thanks for pickup this up. I’ve created a test url that uses the same content security policy.

https://sparco2.test4.sparco.nl/demopushr.html

Thanks!

Hi there, it looks like your security policy is super restrictive and is not letting many third party integrations (including Google Analytics & Cloudflare) function properly. There isn’t much we can do on our end. Perhaps you can look into relaxing your security policy.

The CSP is no more restrictive than the one used by this forum page (granted, the lists are different but restrictive non the less which is a good thing). We are open to changing the CSP on the site but need help understanding what needs to change or possibly how to deploy Webpushr in an alternative way. The browser error regarding the CSP is this:

Refused to execute inline event handler because it violates the following Content Security Policy directive: … Either the ‘unsafe-inline’ keyword, a hash (‘sha256-…’), or a nonce (‘nonce-…’) is required to enable inline execution.

We are not willing to change the CSP to enable unsafe-inline. This would be a big security risk for any site and I think why is self explanatory but to prove that point: Google search results for “csp should i enable unsafe-inline”.

The other 2 options seem to be using a nonce or providing a hash but given that the script inlining occurs out of our execution control I do not believe this is possible.

How we currently have set this up (see below). Is there an alternate configuration that will allow this to work where we would not have to add script-src: unsafe-inline?

Thank you in advance,
-Igor


POC HTML page demopushr.html

<html>
<head></head>
<body>
<h1>Demo</h1>

<!-- a hash is provided in the CSP for this script: sha256-3lSTGUZawbckE01O/wREJmT57/nl9ZNyPmzBJ5URy5s= -->
<!-- start webpushr tracking code-->
<script>(function(w,d, s, id) {if(typeof(w.webpushr)!=='undefined') return;w.webpushr=w.webpushr||function(){(w.webpushr.q=w.webpushr.q||[]).push(arguments)};var js, fjs = d.getElementsByTagName(s)[0];js = d.createElement(s); js.id = id;js.async=1;js.src = "https://cdn.webpushr.com/app.min.js";
fjs.parentNode.appendChild(js);}(window,document, 'script', 'webpushr-jssdk'));
webpushr('setup',{'key':'key_here' });
</script>
<!-- end webpushr tracking code -->
</body>
</html>

webpushr-sw.js

importScripts('https://cdn.webpushr.com/sw-server.min.js');

Trimmed down CSP header for the purposes of this POC

style-src 'self' https://bot.webpushr.com https://cdn.webpushr.com https://analytics.webpushr.com;
script-src 'self' 'sha256-3lSTGUZawbckE01O/wREJmT57/nl9ZNyPmzBJ5URy5s=' https://bot.webpushr.com https://cdn.webpushr.com https://analytics.webpushr.com;
img-src 'self' data: https://bot.webpushr.com https://cdn.webpushr.com https://analytics.webpushr.com;
connect-src 'self' https://bot.webpushr.com https://analytics.webpushr.com;
font-src 'self';
default-src 'self';
frame-src 'self';
block-all-mixed-content;
object-src 'none'

Thank you for the detailed response. Can you please explain why it is also blocking commonly used APIs such as google analytics & cloudflare? We see the following error in web console on your test page. Just want to make sure we aren’t missing anything here.

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'sha256-3lSTGUZawbckE01O/wREJmT57/nl9ZNyPmzBJ5URy5s=' https://cdn.webpushr.com https://www.google.com https://www.google-analytics.com https://ajax.googleapis.com https://cdnjs.cloudflare.com https://code.jquery.com https://maxcdn.bootstrapcdn.com https://www.gstatic.com https://cdn.ckeditor.com". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

Hi,
I believe you are misreading the message in the browser. Broken down into parts the message states:

Part 1 - Error message

Refused to execute inline event handler because it violates the following Content Security Policy directive

Translation: There is an inline event that could not be executed because it violates the CSP directive.

Part 2 - CSP Directive

It then prints out the entire CSP directive/rule that is being violated which is:

script-src 'self' 'sha256-3lSTGUZawbckE01O/wREJmT57/nl9ZNyPmzBJ5URy5s=' https://cdn.webpushr.com https://www.google.com https://www.google-analytics.com https://ajax.googleapis.com https://cdnjs.cloudflare.com https://code.jquery.com https://maxcdn.bootstrapcdn.com https://www.gstatic.com https://cdn.ckeditor.com

Part 3 - Hint on fixing CSP

And then the last part of the error has a suggestion on how to fix directive violation.

Either the ‘unsafe-inline’ keyword, a hash (‘sha256-…’), or a nonce (‘nonce-…’) is required to enable inline execution.


Regarding the other items in our CSP header: I did not mention that we allow google analytics or cloudflare because it does/did not seem relevant (we allow other things too like jquery and ckeditor and other 3rd party libraries hosted on cdns outside of our domain) but that should have no impact on Webpushr. For simplicity I included just the relevant declarations in my previous post/comment.

Ok, we understand now. Thank you. Can you please send us an e-mail at support@webpushr.com and refer to this thread?

Can you please add the following meta tag in your webpage (inside <head> tag) and check if works?
It basically allows the inline-script and inline-style for webpushr.com

<meta http-equiv="Content-Security-Policy" content="style-src 'unsafe-inline' *.webpushr.com; script-src 'unsafe-inline' *.webpushr.com; worker-src 'self' *.webpushr.com; default-src 'self' *.webpushr.com;">

Hi,
That header would not only allow/enable unsafe-inline for webpushr it would allow/enable it on our entire site. Each item after a declaration is self standing meaning they are independent.

Example: script-src 'unsafe-inline' *.webpushr.com would mean allow both unsafe-inline and also anything hosted on *.webpushr.com.

Adding <meta http-equiv="Content-Security-Policy" ... to the header is just a replacement for the CSP http header but the header takes priority if both are present meaning I can add it but it would be ignored by most browsers.

I will send an email to your support referencing this ticket, thank you for your help so far.

-Igor

We’ve found a way to implement without having to use script-src 'unsafe-inline'. Can you please test it out and let us know what you think?

Step 1: Copy/Paste our JS code snippet in a separate JS file (example: webpushr.js) that is hosted on your server/domain and include the JS file in your html, like the following:
<script src="/webpushr.js"></script>

Step 2: Make sure you select the following prompt type:
image

Step 3: Add the following to your header for Content Security Policy:

default-src 'self' *.webpushr.com; style-src 'unsafe-inline'; script-src 'self' *.webpushr.com 'unsafe-hashes' 'sha256-vfEDVcIrttabzt/ULucAN6Y4MKP2N3ucsFFYRUyr+vM=' 'sha256-nfgK8kOaeqfdsstuAQy5auqrVPcmmwMqmCkSlhq30c4=' 'sha256-6u66jhMevt7JhJ9ju9BNHI8lJ6P/ObG5hu5h57mvdBw=' 'sha256-il8xrKO6TDWc+EtJ8doG9doUgh/v9IPD8kKXZ0RqDnc=' 'sha256-sQSlDXgmyHqLPFUfL666omsrRK6mj05pbfO/v4cWpSg=' 'sha256-UvP3X3ceGivIcNgJzqbvmjNMLrg+7DZOUDyjOy20x1U=' 'sha256-xXfIGsY14XpKCS0PXICHzBKxF5kkF6VzYUeD/6J8KMc=' 'sha256-h1sUDJEGpLgMpGtxnKpnf2NoT3miMhP0IuMrPHiQfC4=' 'sha256-847XGfV1UAhJ+hFZ0pO0o1vAB2McNeYP4twqdaH/DDk=' 'sha256-ZtcjP6G+65RkXXwd0y719+RaBaVzSEBIR23mlF/V/60='

the 'unsafe-hashes' enables the specifically declared inline-event handlers associated with Custom Prompt Type 2 & our Subscription Bell feature that need to run to enable web push notifications.

Our design goal at this point, based on this thread, is to move all event handler logic to our main SDK/JS file that is served from cdn.webpushr.com. When that happens, you will no longer need to use 'unsafe-hashes' in your CSP policy. Since we are a couple weeks away from making that happen, we wanted to give you something that you can start using right away.

Update 30th November 2020: We have moved all in-line event handler logic to our main JS file. You no longer need to use ‘unsafe-hashes’ in CSP. Please use the following policy to enable webpushr:

default-src 'self' *.webpushr.com; style-src 'unsafe-inline';

Thank you for your excellent support and time to get us an answer. We will have to evaluate our user base to see if this is a solution we can. That will be based on our findings in Google Analytics as the CSP Level 3 specification is still in draft and has not yet been implemented in either Firefox or Safari. The specification (as well as articles about the specification] also mention to avoid this fix when possible so we will have to evaluate the risks before we implement.

You mentioned that you are going to start work on moving all event handler logic to the main JS file. Do you have a rough timeline for when that will be ready for general release? I am not looking for an exact date more like a month of the year or perhaps a quarter (example Q1 of 2021).

Again, thank you for your support and getting an answer to our question/problem so fast.
-Igor

Thank you for the quick feedback.

We have done 80% of development on our end and we believe that we should be able to make this GA (push out in production) by Friday November 27th 2020. All in-line event handlers will be moved to our main JS file.

We will keep this thread updated.

That is great news, much sooner than we expected. Thank you very much and we will keep monitoring the thread for updates.

We have moved all in-line event handler logic to our main JS file. You no longer need to use ‘unsafe-hashes’ in CSP. Please use the following policy to enable webpushr:

default-src 'self' *.webpushr.com; style-src 'unsafe-inline';

Thank you very much especially for how fast you were able to make the changes. We successfully tested it with the following relevant CSP settings (see below) where the hash is the hash for the static loading script on our html page.

default-src 'self';
connect-src 'self' https://bot.webpushr.com https://analytics.webpushr.com;
style-src 'self' 'unsafe-inline';
script-src 'self' https://cdn.webpushr.com 'sha256-q2zNrfX7rDIA808rEAkgT7ObI3MBCbpyRmOzlD63xLg=';
img-src 'self' data: https://cdn.webpushr.com;
block-all-mixed-content;
object-src 'none'

Consider this ticket answered / closed and thank you again.

Fantastic! thank you for the update. FYI - below is a list of all Webpushr endpoints w/ brief description:

bot.webpushr.com
Serves prompts & saves subscriber-related (endpoint, last visit, etc.) information

analytics.webpushr.com
Saves impression related information for opt-in funnel analytics

notevents.webpushr.com
Saves delivery, clicks, etc information related to the actual push notifications

cdn.webpushr.com
Serves our SDK (app.min.js) file

api.webpushr.com
API & Third-part integration endpoint