I'm developing a Chrome extension in MV3. I need to integrate Stripe with this extension. This extension overrides the new tab. And I'm using ReactJs and Webpack.
NPM Package using: React Stripe.js
Right now I'm getting
stripe.esm.js:30 Refused to load the script 'https://js.stripe.com/v3' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
I've tried adding
"content_security_policy": {
"extension_pages": "script-src 'self' https://js.stripe.com/v3; object-src 'self'; frame-src https://js.stripe.com/v3"
}
in manifest.json but I get this.
What am I doing wrong? Is it not possible to use it like this in MV3?
Your help is appreciated.
Basically the simple and straight forward answer is that you cannot do your implementation this way. First “Remotely hosted code is no longer allowed; an extension can only execute JavaScript that is included within its package.” as per the chrome developer documentation [0].
Stripe has also addressed this issue in their GitHub which you can read more about here [1].
As for the best way to handle this situation is for your extension to generate a link to an external website that you would create. In there, you’d be able to create a CheckoutSession or even integrate with PaymentElements.
I hope this shed some light on how to move forward.
[0] https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#feature-summary
[1] https://github.com/stripe/stripe-js/issues/273
Related
Hi I am developing NodeJS project with using pug.
Not able to load the api https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.js file from pug template.
In chrome getting the error in console.
Please find the below image for reference
Please help to resolve this issue.
Thanks.
It's complicated to answer without having the code. But it seems that it can't load because of a security problem. And kaspersky gets involved.
Maybe try to edit the metq
"mapboxlg" is not defined
Maybe it's because the CDN only allows HTTPS requests and given your localhost development link it's only HTTP and for the CDN it's not secure.
This is just speculation because again, you didn't put any code
You need to specify the hosts for csp whitelist in res headers of your pages.
Refer to this for detailed information:
CSP directives
After stumbling over the same problem and researching for a day, this worked for me:
Before you render you page, set the header like below:
res.set({
'Content-Security-Policy': `default-src 'self' http: https:;block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data: blob:;object-src 'none';script-src 'self' https://api.mapbox.com https://cdn.jsdelivr.net 'unsafe-inline' 'unsafe-eval';script-src-elem https: http: ;script-src-attr 'self' https://api.mapbox.com https://cdn.jsdelivr.net 'unsafe-inline';style-src 'self' https://api.mapbox.com https://fonts.googleapis.com 'unsafe-inline';worker-src 'self' blob:`
});
Now either you can keep doing this before rendering every page, or place this code in a middleware in you main app, just before you've defined your router for rendering the html pages.
Something like this:
<appName>.use( (req, res, next)=>{
res.set....//as done above
next();
});
In future, if something stops working, inspect browser window and look in console, you'll just need to whitelist some other trusted sources.
I am trying to integrate Stripe but facing the following issues.
When I am loading normally via ngx-stripe, it's giving me this error in the console.
Refused to load the script 'https://js.stripe.com/v3/' because it
violates the following Content Security Policy directive: "script-src
'self' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly
set, so 'script-src' is used as a fallback.
I change content_security_policy in manifest to "script-src 'self' https://js.stripe.com/v3/; object-src 'self' " but it's giving me this error in the console.
Uncaught EvalError: Refused to evaluate a string as JavaScript because
'unsafe-eval' is not an allowed source of script in the following
Content Security Policy directive: "script-src 'self'
https://js.stripe.com/v3/".
After that, I tried adding content_scripts but it's giving me this error and don't let me to import the zip file as well while saying
Could not load javascript '' for content script.
How can I overcome this issue? and is it possible to integrate Stripe into a chrome extension because Stripe only works via https but extension working with chrome://
The answer provided by #EndersJeesh works for me with Chrome extensions with manifest version 2.
I was wondering whether it was going to stop working in manifest version 3:
https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#remotely-hosted-code
The Remotely Hosted Code says that you will not be able to load remote hosted code so I imagine that loading https://js.stripe.com/v3 will not be possible.
The best solution would be for all the Stripe code to be embedded in the extension but there's no npm package for this Stripe code.
Any comments from #EndersJeesh or others would be appreciated.
I ran into these and several subsequent issues integrating stripe into a chrome extension.
Explanation:
I'll first state what I believe was happening. Using the stripe react libraries, I believe they have an inline js call somewhere, causing the error you're seeing about js.stripe.com. I think this would be fixed by adding unsafe-inline into your content_security_policy, but that will not be executed by chrome extensions per the extension CSP.
Solutions:
So here are the various things I did (solving one typically led to having to solve the next set of errors).
I initially had my constent_security_policy set to
"content_security_policy": "script-src 'self' https://js.stripe.com/v3; object-src 'self';"
I was running into your issue above, and so I added the script into my header call, leading my index.html file to be the following:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://js.stripe.com/v3" async></script>
</head>
<body>
<div id="modal-window"></div>
</body>
</html>
That resolved the first set of errors which matched yours above, but it led to the next set of issues:
I then hit a series of errors around Refused to frame ... because it violates the following Content Security Policy directive: "frame-src"..., so I fixed these by adding to my content_security_policy the following:
frame-src https://js.stripe.com/v3
So my final version of my content_security_policy is as follows:
"content_security_policy": "script-src 'self' https://js.stripe.com/v3; object-src 'self'; frame-src https://js.stripe.com/v3"
I hope that does it for you. It took several hours to work through all of that for me.
Background
The idea of the Content Security Policy was to tell web-browsers what content to load from where. This means that attackers should not be able to inject their own code if, for example, 'unsafe-inline' was not explicitly allowed (which is not the best thing to do).
Google also released a CSP Evaluator, which is designed to find possible mistakes in your policy. With the default settings, the tool recommends using the 'strict-dynamic' policy for 'script-src'. The idea behind it is that you write a loader for whichever JavaScript sourcees you require and forbid everything else.
The Problem
What is considered the "correct" way to implement such a loader? Should the loader be written yourself (see below for example) or should a tool be used to create such a loader? (Please note that this question is not asking for a specific tool recommendation)
Example
var imported = document.createElement('script');
imported.src = '/path/to/imported/script';
document.head.appendChild(imported);
Context
My website currently has the following policy:
default-src 'none';
img-src 'self';
style-src 'self' https://stackpath.bootstrapcdn.com 'sha256-bviLPwiqrYk7TOtr5i2eb7I5exfGcGEvVuxmITyg//c=';
script-src https://use.fontawesome.com https://code.jquery.com https://cdnjs.cloudflare.com https://stackpath.bootstrapcdn.com;
base-uri 'none';
form-action 'none';
frame-ancestors 'none';
Google's tool suggested the following:
Host whitelists can frequently be bypassed. Consider using 'strict-dynamic' in combination with CSP nonces or hashes.
As such, I want to implement a loader to load these JS frameworks and I want to know how to best approach this issue.
An immediate answer is that as long as the script you're dynamically loading (/path/to/imported/script) is hosted in a domain that you've already whitelisted in script-src, you don't have to modify your CSP or change your loader -- everything will work as expected.
However, a broader problem is that your script-src whitelist includes domains that host Javascript which can be used by an attacker who finds a markup injection bug in your application to bypass your CSP. For example, https://cdnjs.cloudflare.com hosts Angular (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js) which can be used by an attacker to convert an HTML injection into arbitrary script execution (here is a paper about this).
The suggestion in the CSP Evaluator tool is to switch your application to rely on a script-src which uses CSP nonces instead of the whitelist. To do this you would need to follow the process outlined at https://csp.withgoogle.com/docs/strict-csp.html -- basically, make sure that every <script> element has a correct nonce attribute which changes for every page load, or instead use CSP3 hashes for static scripts.
Your CSP would then look like:
... script-src 'nonce-[random-value]' 'strict-dynamic' 'unsafe-inline' https:; ...
If you use 'strict-dynamic', your script loader does not have to change because browsers will automatically trust scripts added to your page via programmatic APIs such as appendChild().
In my extension I want to use my own WebAssembly module.
After loading my module (to background.html, or popup.html), I catch the compile error:
CompileError: WebAssembly.compile(): Wasm code generation disallowed by embedder.
Are wasm modules not supported in Chrome Extensions?
It seems from this issue that Chrome requires script-src: 'unsafe-eval' CSP directive be active for WebAssembly compilation. See this discussion as to why this is the case, at least for now.
Chrome Extensions come with default restrictions on CSP; that includes not allowing unsafe-eval. Some of the restrictions cannot be lifted; in this case, you can allow unsafe-eval by adding a manifest key:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
This should be enough to test if Wasm works in extensions. But heed this warning from documentation:
However, we strongly recommend against doing this. These functions are notorious XSS attack vectors.
Instead of allowing unsafe-eval for your whole extension, you can sandbox code that requires it, using the following approach from the docs:
Using eval in Chrome Extensions. Safely.
The gist of it is to create a separate page in your extension, where unsafe-eval is allowed but Chrome API access is disallowed; you then embed this page in your extension and communicate with it using postMessage().
Chrome implemented special policy 'wasm-eval' exclusively for apps and extensions to resolve this problem. It is chrome-specific, but slowly moving into CSP and WebAssembly standards. Just replace 'unsafe-eval' with 'wasm-eval' in #Xan's solution.
Note though, this is still an attack vector and it's your responsibility to verify the source of executed assembly. See for example uBlock's author thoughts on this policy.
I tried the 'unsafe-eval' and 'wasm-eval' provided by the other answers here but it didn't fix it. Turned out it's specific to the website. If I try it on Github, it doesn't work. But on reddit.com it works. Below is the error I'm seeing in Chrome developer mode. This is for Chrome extension made using Blazor NET6 with AOT. Hopefully someone finds this useful.
CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder
window.Module.s.printErr # blazor.webassembly.js:1
(anonymous) # blazor.webassembly.js:1
async function (async)
(anonymous) # blazor.webassembly.js:1
window.Module.s.instantiateWasm # blazor.webassembly.js:1
createWasm # dotnet.6.0.0.cnc7cl383g.js:1
(anonymous) # dotnet.6.0.0.cnc7cl383g.js:1
blazor.webassembly.js:1 Uncaught (in promise) CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder
at blazor.webassembly.js:1
at async blazor.webassembly.js:1
I tried it in typo-script on a TYPO3-system and 'unsafe-eval' or 'wasm-eval' won't work. :-(
I defined it in the .htaccess and it works. :-)
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin {linkToDomain}
Header set Access-Control-Allow-Credentials true
Header set Content-Security-Policy "default-src 'self' blob: 'unsafe-eval' 'wasm-eval' {other code ...} ; {other code ...} script-src 'self' 'unsafe-eval' 'wasm-eval' {other code ...}; object-src 'self' 'wasm-eval';{other code ...}"
</IfModule>
P.S. Safari makes problems. After adding a site.manifest, extending the Content-Security-policy for default-src in TypoScript od TYPO3 and .htaccess it seems to work. (see above)
It seems to me, that every browser works different.
I'm trying to build a chrome extension, but for some reason I can't seem to make API requests to SoundCloud or load Jquery.
I know it's because of this:
I will load jquery as such:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
And in my console, I will recieve
Failed to load resource: net::ERR_FAILED
chrome-extension://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
The same thing happens for the soundcloud api:
chrome-extension://api.soundcloud.com/tracks?q=buskers&client_id=xxxxxxxxxx&format=json&_status_code_map[302]=2
Why does chrome-extension// keep coming in front of the urls and how do I stop it?
According to Content Script Policy (CSP), script resource can only be loaded from the extension's package. This will make extensions more secure and ensure that extension will only execute the code you approved.
Solution 1: Download the specific version of jQuery file, include it to your package and then load it into document.
<script src="js/jquery.1.11.1.min.js"></script>
Solution 2: Actually you can relax the limitation by defining the whitelist of resource origins in manifest file. You could refer to this for more details if you have a need to load external js file for some reasons.
"content_security_policy": "script-src 'self' https://ajax.googleapis.com https://api.soundcloud.com/tracks?q=buskers&client_id=xxxxxxxxxx&format=json&_status_code_map[302]=2; object-src 'self'"
Note:
Whitelisting resource only allow to be loaded over the following protocol: HTTPS, chrome-extension, and chrome-extension-resource. Please use https to load the external library if you want to adopt whitelist solution.
Use whitespace to separate domains form each other if you want to define multiple domains in whitelist.
"content_security_policy": "script-src 'self' https://domain1.com https://domain2.com;"
try this
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>