"Refused to load the script" chrome 扩展中的错误

"Refused to load the script" error in chrome extension

SO 上有很多与此类似的问题,但是 none 解决了我的目的。
我正在创建一个类似于 chrome 的 'pinterest' 扩展。它在网页上注入脚本,收集图像,然后 post 它在某个地方。一切正常,但是当我在 pinterest 上 运行 时,它给了我这个错误:

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.


我知道这与 Content Script Policy 有很大关系(而且我对此了解不多)但是,我关注了 this and this link 这给了我足够的信息来了解什么是 CSP 以及如何使用它。
我已经完成了所需的一切(我认为的),但它仍然无法正常工作。这是我的 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'"
}


在某一点上,我也认为这里面可能有些东西实际上无法完成,但是,我然后尝试了 BUFFER 扩展,它也可以成功地将他们的脚本注入到 pinterest 上,这意味着这件事在某种程度上是可能的。此外,不要忘记像 AdBlocker 这样的扩展程序适用于每个站点,它们还必须从远程服务器中提取一些资源。他们是否以任何方式绕过 CSP,或者有一些我不知道或错过的非常重要的东西。任何 suggestions/tips 如何做到这一点?

扩展中有 3 个 CSP 在起作用:

  • content_security_policy指令只适用于扩展自己的页面(如后台页面)。如果未指定,则默认为 script-src 'self'; object-src 'self' 并具有 some restrictions on how it can be modified.

  • 内容脚本上下文不受此 CSP 的约束。 unsafe-eval is unrestricted(因为您可以用任意代码执行 executeScript),但是,内联脚本和远程脚本限制不适用于内容脚本,因为:

  • 页面 DOM 中的任何脚本,无论是内联脚本还是 <script src="..."> 标记,都在页面 本身的上下文中执行 并且受制于页面本身的 CSP。正好有一个例外,在页面 will bypass inline code restrictions 中注入一个 <script> /* code */ </script> 用于 立即 执行。

您所看到的显然是尝试通过将 <script src="https://domain_name.com/my_script.js"> 注入页面来加载远程脚本的结果。这受制于页面自己的 CSP 并且失败了。

  1. 理论上,您可以通过使用 webRequest 拦截和劫持响应 headers 来影响页面自身的 CSP。但是,这不是一个好方法:您通常会干扰 third-party 页面的安全性。没有人会为此高兴。

  2. 您可以做的是使用 XHR 在后台页面加载脚本,然后:

    • 使用chrome.tabs.executeScript({code: ...})将其注入到内容脚本上下文中,不受页面CSP的约束;

    • 将其传递给上下文脚本,以便可以通过将 <script>...</script> 添加到 DOM 来将其注入页面,只要它绕过页面的 CSP不要进一步违反它(通过加载更多脚本或使用 eval/inline 代码)。

      P.S.: 正如 Rob W 所建议的,如果您打算这样做,那么内容脚本可以使用 XHR 本身(假设,如您所见,https来源)

如果不禁用 CSP,您将无法注入未列入白名单的脚本。

扩展脚本不受此限制,因此将文件托管在您的扩展包中,在 web_accessible_resources 中声明它,您应该能够 运行 该脚本。

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.
};

正如@Xan 所引用的,"content_security_policy" 应用于扩展页面,看来您正在将远程脚本注入当前网页,这违反了当前页面的 CSP。

一种推荐的方法是制作远程脚本的本地副本,但是,如果您有充分的理由将其托管在服务器中,我建议您对服务器进行 ajax 调用背景页面,然后调用chrome.tabs.executeScript将代码注入当前页面。

代码片段如下所示:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
    chrome.tabs.executeScript(tabId, {"code": xhr.responseText});
xhr.open("GET", SERVER_SCRIPT_URL);
xhr.send();

我遇到了与 google 分析相同的问题,并通过将 url“https://www.google-analytics.com/analytics.js”添加到权限数组来解决:

"permissions": ["activeTab", "storage","https://www.google-analytics.com/analytics.js"],