Hi,
I noticed that the checkout JS was showing an error on the console when the page loaded.
Adding 'unsafe-inline' to the Content Security Policy(CSP) as suggested by the error message solved the problem. However, I don't want to use the 'unsafe-inline' directive as it applies to all scripts. Is there any alternative way to let the script perform its job correctly? (eg: hash, nonce, etc.)

This is a fair ask.
The reason for this is, we pre-render into the button iframe, and there are some inline scripts in there which need to be run in the context of the frame. I think our options are either:
Out of interest -- is this actually preventing the button from rendering, or just causing noise in the console?
@bluepnume Thanks, the proposed solutions sound good. Solution 1. would be best!
is this actually preventing the button from rendering, or just causing noise in the console?
The button does render. I don't know if and what functionality breaks though. That is because I didn't play with it too much as I went looking into fixing the error being thrown the moment I saw the console error.
Quick thought in the mean time -- can you use the strict-dynamic csp directive? In theory that should allow checkout.js, which is trusted, to dynamically add its script tags.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
I've actually removed the unsafe-inline now because whatever I'm doing with checkout.js is functionally working well except for the fact that there's a console error. (Which is interesting because then why the error? :D)
The strict-dynamic CSP directive should work but that needs a hash/nonce as well. It would take a bit of time to generate and supply the nonce every request in our app. If I notice that something is breaking because of the console error then I will pursue it.
I'm also running into this issue. Any plans to get rid of the error when not using the 'unsafe-inline' CSP directive?
It doesn't seem to break functionality, but causing errors in console and logs.
@bluepnume would you happen to have an update for this issue or could you point me to the part of the code responsible for these errors/warnings? I'd really appreciate that.
It's odd the functionality for the button seems unaffected even with these errors still showing up on the console.
I am running into the same issue. My current policy is: script-src 'self' https://www.paypalobjects.com/api/checkout.js https://www.paypal.com; because I wanted to atleast restrict scripts and I get this error:
dom.js:191 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' https://www.paypalobjects.com/api/checkout.js https://www.paypal.com". Either the 'unsafe-inline' keyword, a hash ('sha256-6HiAvbu6ZalOK8cQJi+KIF4ZEj3ZFT5mcDxw2RknrZ4='), or a nonce ('nonce-...') is required to enable inline execution.
writeElementToWindow @ dom.js:191
(anonymous) @ index.js:1162
_loop @ promise.js:156
ZalgoPromise.dispatch @ promise.js:147
ZalgoPromise.then @ promise.js:240
(anonymous) @ index.js:1138
ZalgoPromise.try @ promise.js:393
ParentComponent.createPrerenderTemplate @ index.js:1125
showContainer:memoized @ decorators.js:13
(anonymous) @ index.js:167
_loop @ promise.js:156
ZalgoPromise.dispatch @ promise.js:147
ZalgoPromise.then @ promise.js:240
(anonymous) @ index.js:166
ZalgoPromise.try @ promise.js:393
ParentComponent.tryInit @ index.js:1283
ParentComponent.render @ index.js:115
(anonymous) @ index.js:488
ZalgoPromise.try @ promise.js:393
Component.render @ index.js:487
callOriginal @ util.js:338
(anonymous) @ hacks.js:170
obj.(anonymous function) @ util.js:334
(anonymous) @ button.js:2
dom.js:76 GET https://www.paypal.com/tagmanager/pptm.js?id=localhost&t=xo net::ERR_BLOCKED_BY_CLIENT
(anonymous) @ dom.js:76
ZalgoPromise @ promise.js:39
__webpack_exports__.j @ dom.js:42
(anonymous) @ pptm.js:34
(anonymous) @ setup.js:147
(anonymous) @ util.js:75
setup @ setup.js:165
./src/index.js @ setup.js:169
__webpack_require__ @ bootstrap 917d40a7d10b147313f6:19
./src/load.js @ load.js:31
__webpack_require__ @ bootstrap 917d40a7d10b147313f6:19
./node_modules/Base64/base64.js @ bootstrap 917d40a7d10b147313f6:62
(anonymous) @ bootstrap 917d40a7d10b147313f6:62
I originally tried a default-src 'self' policy and then making exceptions for everything needed. I ended up with this policy default-src 'self'; script-src 'self' https://www.paypalobjects.com/api/checkout.js https://www.paypal.com; img-src *; connect-src https://www.paypal.com; frame-src https://www.sandbox.paypal.com; and these remaining errors:
errors.log.
@bluepnume Any updates on getting a fix for this? I'm also hitting it with my recently deployed CSP, and it's a very noisy error (we're reporting CSP errors for logging). I am using this via Braintree's Web Drop In, if it matters.
This is solved by the new payments sdk, in pilot. We will accept a nonce as a parameter. Will update here when it goes live.
@bluepnume what is the current status here? I am using the Paypal Plus Wordpress plugin and they said I should contact PayPal directly: https://wordpress.org/support/topic/content-security-policy-problem/#post-11058950
I am having problem with the CSP. No matter what I am trying to add to my list of CSP, the ones from the iframe are having problems... It also does not work with "unsafe-inline".
I am setting this up for a client to whom you sold successfully the PayPal Plus Option. Now they want to see something and I am really having problems getting this work.
Any idea? Who can help out?
I found some "dns-prefetch" stuff in the head of the page. Maybe this causes the issue?
@bluepnume Is the nonce available in 5.0?
@bluepnume Could we get the nonce parameter backported to v4? Upgrading to the new APIs will take a while, and I'd like to have our current implementation compatible with CSP.
@shanecav84 this is unlikely -- we already have a large backlog of items so backporting features to older versions isn't the biggest priority. Hoping the upgrade guide at https://developer.paypal.com/docs/checkout/reference/upgrade-integration/#4-set-up-the-transaction will be helpful and sorry for the extra pain
@bluepnume I'm having a lot of issues integrating PayPal into a Chrome extension due to the restrictions that extensions have for executing inline scripts (unsafe-inline cannot be enabled). Any ideas on how to get around this? It's not clear to me if there's any way to add a nonce parameter in an extension. I should mention that the extension is run entirely client side, so I'm looking to do the client side only integration. Thanks.
Same with latest paypal module for prestashop (1.7.6.7)
Using checkout "in context" gets data forwarded to "javascript:ECInContext()"
You must turn on unsafe-inline for this to work (info) https://apimirror.com/http/headers/content-security-policy/form-action
'unsafe-inline'
Allows the use of inline resources, such as inline
Most helpful comment
i just can't believe this is a billion dollar company...