问题
There are a lot of questions on SO similar to this one however none of them solved my purpose.
I'm creating a 'pinterest' like chrome extension. It injects script on webpage, collect images and then post it somewhere. Everything is working perfectly however when i run this on pinterest itself, it gives me this error:
Refused to load the script 'https://domain_name.com/my_script.js' because it violates the following Content Security Policy directive: "default-src 'self' https://.pinterest.com https://.pinimg.com *.pinterest.com *.pinimg.com *.google.com connect.facebook.net .google-analytics.com https://.googleapis.com .gstatic.com https://.facebook.com *.facebook.com www.googleadservices.com googleads.g.doubleclick.net platform.twitter.com *.tiles.mapbox.com *.online-metrix.net *.bnc.lt bnc.lt *.yozio.com 'unsafe-inline' 'unsafe-eval'". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
I know this has a lot to do with Content Script Policy
(and i don't know much about it) however, i followed this and this link which gave me enough info on what is CSP and how to use it.
I've done everything (what i think) that is required but it still is not working. Here is my manifest.json
{
"manifest_version": 2,
"name": "Image Posting",
"description": "This extension enables you to post images",
"version": "1.0",
"browser_action": {
"name": "Image Posting"
},
"homepage_url": "https://www.domain_name.com/",
"background":{
"scripts":["background.js"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery.js", "content.js"]
}
],
"icons": {
"128": "icon_128.png",
"16": "icon_16.png",
"48": "icon_48.png"
},
"permissions": [
"activeTab",
"notifications"
],
"web_accessible_resources": [
"icon_48.png"
],
"content_security_policy": "default-src 'self' https://domain_name.com/my_script.js; script-src 'self' https://domain_name.com/my_script.js; style-src 'self' https://domain_name.com/my_style.css; 'unsafe-inline' 'unsafe-eval'"
}
at a point, i also thought that there might be something in this which cannot be actually done however, i then tried BUFFER extension, and it can successfully inject their script on pinterest as well which means this thing is somehow possible. Also, not to forget that extension like AdBlocker works on every site and they also must be pulling some resources from a remote server. Are they bypassing CSP by any means or there is something really crucial that i don't know or missed. Any suggestions/tips on how to do this?
回答1:
Without disabling the CSP, you cannot inject scripts that are not whitelisted.
Extension scripts are exempt from this restriction, so host the file in your extension package, declare it in web_accessible_resources and you should be able to run the script.
var s = document.createElement('script');
s.src = chrome.extension.getURL('script.js'); // In web_accessible_resources
(document.head || document.documentElement).appendChild(s);
s.onload = function() {
s.remove(); // Clean up, just to be nice.
};
回答2:
There are 3 CSPs at play in extensions:
content_security_policy
directive only applies for extension's own pages (such as the background page). If not specified, it defaults toscript-src 'self'; object-src 'self'
and has some restrictions on how it can be modified.Content script context is not subject to this CSP. unsafe-eval is unrestricted (since you can do
executeScript
with arbitrary code anyway), however, inline script and remote script restrictions just don't apply to content scripts, because:Any script in the DOM of the page, be it inline or
<script src="...">
tag is executed in the context of the page itself and is subject to the CSP of the page itself. There is precisely one exception, injecting a<script> /* code */ </script>
in the page will bypass inline code restrictions for immediate execution.
What you're seeing is apparently a result of trying to load a remote script by injecting a <script src="https://domain_name.com/my_script.js">
into the page. This is subject to the page's own CSP and fails.
In theory, you could affect the page's own CSP by intercepting and hijacking the response headers using
webRequest
. However, this is not a good approach: you are generally interfering with security of a third-party page. Nobody is going to be happy about that.What you can do is load the script in the background page using XHR, and then either:
Inject it into the content script context by using
chrome.tabs.executeScript({code: ...})
, which is not subject to page's CSP;Pass it to the context script so that it can be injected into the page by adding
<script>...</script>
to the DOM, which bypasses the page's CSP as long as it does not violate it further (by loading more scripts or using eval/inline code).P.S.: As Rob W suggests, if you're planning to do this then a content script can use XHR itself (assuming, as you have,
https
source)
回答3:
As @Xan cited, "content_security_policy"
is applied to extension pages, it seems you are injecting remote script into current web page, which violates the CSP of current page.
One recommended way is to make a local copy of your remote script, however, if you have a good reason to host it in the server, I would suggest you made an ajax call to your server in background page, then call chrome.tabs.executeScript
to inject the code into current page.
Code snippets would look like:
var xhr = new XMLHttpRequest();
xhr.onload = function() {
chrome.tabs.executeScript(tabId, {"code": xhr.responseText});
xhr.open("GET", SERVER_SCRIPT_URL);
xhr.send();
回答4:
I faced the same issue with google analytics and solved by adding the url "https://www.google-analytics.com/analytics.js" to permission array:
"permissions": ["activeTab", "storage","https://www.google-analytics.com/analytics.js"],
来源:https://stackoverflow.com/questions/36737818/refused-to-load-the-script-error-in-chrome-extension