chrome 扩展中的“拒绝加载脚本”错误

Posted

技术标签:

【中文标题】chrome 扩展中的“拒绝加载脚本”错误【英文标题】:"Refused to load the script" error in chrome extension 【发布时间】:2016-08-12 18:41:20 【问题描述】:

关于 SO 有很多与此类似的问题,但没有一个能解决我的目的。 我正在创建一个类似于 chrome 扩展的“pinterest”。它在网页上注入脚本,收集图像,然后将其发布到某处。一切正常,但是当我在 pinterest 本身上运行它时,它给了我这个错误:

拒绝加载脚本“https://domain_name.com/my_script.js”,因为它违反了以下内容安全策略指令:“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'”。请注意,'script-src' 没有显式设置,因此 'default-src' 用作后备。

我知道这与Content Script Policy 有很大关系(我对此了解不多)但是,我关注了this 和this 链接,它为我提供了关于什么是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,或者有一些我不知道或错过的非常重要的事情。有关如何执行此操作的任何建议/提示?

【问题讨论】:

【参考方案1】:

如果不禁用 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.
;

【讨论】:

嗨,罗伯!如果脚本 可以 与扩展程序捆绑在一起,这是一个不错的选择。我的回答假设它不能(必须经常改变)。 感谢您的回答,但我仍然坚持这一点。我按照你说的做了,我相信这工作正常(这方面还没有错误)。在我添加的脚本中(使用你的方式),我需要像这样调用另一个脚本: loadScript("another_script.js", function() //some stuff ) 我试过这样做 var a= chrome.extension.getURL('another_script.js') 然后 loadScript(a, function() //some stuff ) 但这给了我 getURL 未定义的错误。这种情况有什么问题? @TusharShukla 当您以这种方式加载脚本时,它会在页面上下文中运行。如果您想加载另一个脚本,那么您可以同步使用document.currentScript.src 来检索脚本的基本 URL 并使用它来获取到 another_script.js 的 URL。注意:如果可能,应避免在页面中注入脚本。为什么不能通过声明的内容脚本加载脚本? 想知道您是否也可以通过this question 帮助我..? @TusharShukla 我将推迟回答DelightedD0D 的任务。他在您的问题下的 cmets 表明他理解该主题,并且由于他已经表示有兴趣发布答案,因此我不会干预。【参考方案2】:

扩展中有 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 中的任何脚本,无论是内联的还是 &lt;script src="..."&gt; 标记,都在页面的上下文中执行本身,并受制于页面本身。恰好有一个例外,在页面will bypass inline code restrictions 中注入&lt;script&gt; /* code */ &lt;/script&gt;立即 执行。

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

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

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

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

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

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

【讨论】:

您甚至可以通过 XHR 从内容脚本加载脚本并将其注入页面,除非页面是 https 站点并且脚本来自 http,否则请求会被阻止。但这很好,您不应该在第三方页面上运行任意代码,更不用说在 https 页面中运行不安全(来自 http)的代码了。【参考方案3】:

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

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

代码 sn-ps 看起来像:

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

【讨论】:

【参考方案4】:

我在使用谷歌分析时遇到了同样的问题,并通过将 URL“https://www.google-analytics.com/analytics.js”添加到权限数组来解决:

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

【讨论】:

以上是关于chrome 扩展中的“拒绝加载脚本”错误的主要内容,如果未能解决你的问题,请参考以下文章

Vimeo 内容安全策略错误 - 拒绝加载脚本

由于内容安全策略指令,扩展程序拒绝加载脚本

内容安全策略 [错误] 拒绝加载脚本 safari

chrome 扩展中的 Access-Control-Allow-Origin 错误

Chrome扩展中的Socket通信问题

chrome 扩展中的跨域 XMLHttpRequest