Web扩展 - Iframe源执行脚本时出现内容安全策略错误

时间:2018-04-23 02:39:12

标签: javascript firefox-webextensions content-security-policy content-script

我有一个firefox Web扩展,当单击一个按钮时,它使用内容脚本将HTML注入网页。注入的HTML包含嵌套在几个div中的iFrame。

这里是内容脚本的相关部分:

var iFrame = document.createElement("iFrame");
iFrame.id = "contentFrame";
iFrame.style.cssText = "width: 100%; height: 100%; border: none;";
iFrame.src = browser.extension.getURL("inject-content/inject.html");

var boxDiv = document.createElement("div");
boxDiv.style.cssText = "left: calc(100% - 390px); position: fixed; top: 0px; width: 390px; z-index: 1;"

var zeroDiv = document.createElement("div");
zeroDiv.style.cssText = "position: fixed; width: 0px; height: 0px; top: 0px; left: 0px; z-index: 2147483647;";

var outerDiv = document.createElement("div");
outerDiv.id = outerDivID;

boxDiv.appendChild(iFrame);
zeroDiv.appendChild(boxDiv);
outerDiv.appendChild(zeroDiv);
document.body.appendChild(outerDiv);

如代码所示,iFrame的来源是名为" inject.html"的文件。 inject.html的两个重要特征是:

1)脚本标记(在标题内),引用同一目录中javascript库的文件。

<script src="perfect-scrollbar.js"></script>

2)一段使用&#34; perfect-scrollbar.js&#34;的内联javascript。另外,作为参考,这里是图书馆本身:https://github.com/utatti/perfect-scrollbar

<script>
console.log("Hello World");

var perfectScrollbar = new PerfectScrollbar("#container");
</script>

当我从计算机直接打开文件时(即 - 右键单击​​,使用Chrome打开),它可以正常工作。但是,当我在Firefox中使用我的扩展时,我收到以下错误:

  

内容安全策略:页面的设置阻止了在self(“script-src”)加载资源。

     

来源:       console.log(&#34; hello world&#34;);

     

VA ....

我通读documentation,看起来默认内容安全政策不允许使用内嵌式JavaScript。

相关文件:

  

扩展程序的默认内容安全策略是:

"script-src 'self'; object-src 'self';"
  

这将应用于未使用content_security_policy manifest.json密钥明确设置自己的内容安全策略的任何扩展。它有以下后果:

     

您只能加载扩展程序本地的资源和资源。

     

不允许扩展名将字符串计算为JavaScript。

     

未执行内联JavaScript。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script

我会通过使用import语句来解决内联javascript的问题,但根据Mozilla的说法,Firefox现在不支持这些问题:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

根据文档,可以通过创建脚本的sha-256哈希来允许一些内联Javascript。

https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/content_security_policy

  

允许扩展程序通过在&#34; script-src&#34;中提供脚本的哈希值来执行内联脚本。指令。

     

允许内嵌脚本:<script>alert('Hello, world.');</script>

     

"content_security_policy": "script-src 'self' 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='; object-src 'self'"

和这个

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script

  

或者,您可以从内联脚本创建哈希。 CSP支持sha256,sha384和sha512。

     

Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='

     

生成哈希值时,请不要包含<script>标记,并注意大小写和空格很重要,包括前导或尾随空格。

所以,我通过突出显示&#34; inject.html&#34;中的以下文本来创建我的脚本的sha-256哈希:

Highlighting Example

并使用SHA-256计算器(我选择base-64与示例保持一致):https://hash.online-convert.com/sha256-generator

并更改我的&#34; manifest.json&#34;提交到:

{
    "manifest_version": 2,
    "name": "Summarizer",
    "version": "1.0",

    "description": "Summarizes webpages",

    "permissions": [
        "activeTab",
        "tabs",
        "storage",
        "downloads",
        "*://*.smmry.com/*"
    ],

    "icons":
    {
        "48": "icons/border-48.png"
    },

    "browser_action":
    {
        "browser_style": true,
        "default_popup": "popup/choose_length_page.html",
        "default_icon":
        {
            "16": "icons/summarizer-icon-16.png",
            "32": "icons/summarizer-icon-32.png"
        }
    },

    "web_accessible_resources": [
        "inject-content/inject.html"
    ],

    "content_security_policy": "script-src 'self' 'sha256-GdCLzZEX8DPwLRiIBZvv6ffymh4hz/9NgjmzyPv+lGM='; object-src 'self'"

}

然而,我的错误仍然存​​在!

因此,我的问题是,

如何在不出现此错误的情况下允许我的内联Javascript执行?有没有办法在没有散列的情况下做到这一点?

理想情况下,我希望完全避免使用内联JavaScript,而是将所有内联javascript移动到我的内容脚本文件中。由于Firefox不支持import语句,我是否可以这样做,如果是这样的话,怎么办?我对Babel等工具没有经验。

1 个答案:

答案 0 :(得分:0)

虽然网页上说你可以有尾随/领先的空格,但我遇到了问题。解决方案结果是将我的所有代码放在一行(并重新计算基本64 SHA-256哈希)。

<script>console.log("Hello World");var perfectScrollbar = new PerfectScrollbar("#container",{suppressScrollX: true});</script>