Luoruize
Luoruize

Reputation: 688

Chrome extension refusing to load external scripts

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

Answers (4)

Huy Nguyen
Huy Nguyen

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

gabesoft
gabesoft

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

Samarth Agarwal
Samarth Agarwal

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

user1731468
user1731468

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

Related Questions