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

Web Extension - Content Security Policy Error when Iframe Source Executes Script

我有一个 firefox 网络扩展程序,它使用内容脚本在单击按钮时将 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) 一个脚本标签(在 header 内)引用同一目录中 javascript 库的文件。

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

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

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

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

当我直接从我的电脑打开文件时(即 - right-click,用 Chrome 打开),它工作正常。但是,当我在 Firefox 中使用我的扩展程序时,出现以下错误:

Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src”).

Source: console.log("hello world");

va....

我通读了 documentation,默认内容安全策略似乎不允许 in-line javascript。

相关文档:

The default content security policy for extensions is:

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

This will be applied to any extension that has not explicitly set its own content security policy using the content_security_policy manifest.json key. It has the following consequences:

You may only load and resources that are local to the extension.

The extension is not allowed to evaluate strings as JavaScript.

Inline JavaScript is not executed.

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

Allow the extension to execute inline scripts, by supplying the hash of the script in the "script-src" directive.

Allow the inline script: <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

Alternatively, you can create hashes from your inline scripts. CSP supports sha256, sha384 and sha512.

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

When generating the hash, don't include the <script> tags and note that capitalization and whitespace matter, including leading or trailing whitespace.

因此,我通过在 "inject.html" 中突出显示以下文本来创建脚本的 sha-256 哈希:

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

并将我的 "manifest.json" 文件更改为:

{
    "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 等工具的经验。

尽管网页上说您可以使用 trailing/leading 空格,但我对此有疑问。结果证明,解决方案是将我的所有代码放在一行中(并重新计算 base 64 SHA-256 哈希)。

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