Reputation: 688
I'm building a chrome extension using manifest version 3. The entire point of the extension is to inject an external dynamic script into the page (for example, https://example.com/). I keep receiving the following message:
Refused to load the script 'https://example.com/' 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 tried to add a content_security_policy entry to my manifest file, but I can't seem to get it to work. Assuming that this script that I'm loading will call several additional scripts from different domains, what can be done to enable this?
Upvotes: 4
Views: 4161
Reputation: 53
like this works for me https://stackoverflow.com/a/76009962/14845605
const dynamicScript = fetch(...);
const data = {} // to pass into dynamic script
chrome.scripting.executeScript(
{
target: { tabId: details.tabId },
world: "MAIN", // most important part
func: data => {
(new Function('data', dynamicScript))(data);
},
args: [data] // passing app into func above
}
);
Upvotes: 0
Reputation: 1228
You could use the declarativeNetRequest API to add a rule to modify the CSP header to whatever you need it to be to accept that script. For example something like:
{
"id": 11,
"priority": 1,
"action": {
"type": "modifyHeaders",
"responseHeaders": [
{ "header": "Content-Security-Policy", "operation": "append", "value": "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://example.com" }
]
},
"condition": { "urlFilter": "my-domain.com", "resourceTypes": ["sub_frame"] }
}
Upvotes: 0
Reputation: 2134
Manifest v3 Method
I could not find a way to include a remote script but if it is possible that you can download the external JS file and place it as part of the extension, it will be bundled along with the extension's code and you can refer to it from within your content-scripts as well using a relative URL. Here is how you can do it.
Assuming that you have example.js
downloaded and placed alongside your content script files. In your manifest.json
, add the file to web_accessible_resources
web_accessible_resources: [
...
{
resources: ['example.js'],
matches: ['*://*/*'],
},
],
Next, add the following code to you content-script.
const inject = () => {
var r = document.createElement('script');
r.setAttribute('src', 'chrome-extension://' + chrome.runtime.id + '/example.js');
(document.head || document.documentElement).appendChild(r);
};
inject();
Note that the example.js
file will be immediately injected and executed as soon as the content-script that has the above code runs. Also make sure that if you have a bundler like webpack in place, you need to configure it to include the JS file in the final bundle.
Upvotes: 1
Reputation: 1000
manifest V2
In Chrome extension with manifest V2 you can do it like this:
manifest.json
"content_security_policy": "script-src 'self' https://example.com/;
manifest V3
Remotely hosted code
In Manifest V3, all of your extension's logic must be bundled with the extension. You can no longer load and execute a remotely hosted file. A number of alternative approaches are available, depending on your use case and the reason for remote hosting.
source: https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#remotely-hosted-code
Upvotes: 4