【问题标题】:How to check whether inline JavaScript is disabled (with Tampermonkey)如何检查内联 JavaScript 是否被禁用(使用 Tampermonkey)
【发布时间】:2017-03-11 02:49:08
【问题描述】:

我有一个 Tampermonkey 用户脚本,在 document-start 运行。
如何检查内联 JavaScript 是否被禁用?

【问题讨论】:

  • 在页面上下文中插入一些代码,应该会向您发送消息。如果您没有收到消息(postMessage/custom 事件),那么它没有运行。但是,这并不意味着某些 JavaScript 被禁用。有一些扩展会根据不同的标准选择性地禁用 JavaScript。您是要测试那种被禁用的类型,还是只是所有的 JavaScript 都被禁用?
  • 我特别想测试(来自 Tampermonkey 用户脚本)页面上的所有内联 JavaScript 是否已被禁用,例如使用 uBlock Origin 过滤器,例如 *$inline-script,domain=stackoverflow.com。正如 Brock Adams 所提到的,它似乎是使用 CSP 指令 script-src 'unsafe-eval' * 来实现的。

标签: javascript google-chrome google-chrome-extension tampermonkey


【解决方案1】:

这是有问题的,因为阻止内联 JS 的某些(¿ 大多数?)方法:(a)不阻止 unsafeWindow 操作和(b)抛出未被 try ... catch 块在 Tampermonkey 脚本中捕获的异常.

所以下面的工作,但如果内联 JS 被禁用,你会看到如下错误:

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src 'unsafe-eval' *”。启用内联执行需要使用“unsafe-inline”关键字、哈希(“sha256-6BrJXtaiqFeKY4qCquiR3JgWK2KweFWHCvhZWr4tkxA=”)或随机数(“nonce-...”)。

在控制台中。此类错误很烦人,但不会停止 Tampermonkey 脚本。

工作演示代码:

// ==UserScript==
// @name        Test local JS
// @match       *://stackoverflow.com/questions/*
// @run-at      document-start
// @grant       unsafeWindow
// ==/UserScript==

let gbl_InlineJS_Works = true;
try {
    unsafeWindow.TM_youAliveCanary = true;
}
catch (zError) {
    console.log ("Local JS fails: " + zError);
    gbl_InlineJS_Works = false;
}

if (gbl_InlineJS_Works) {
    var tstScript = document.createElement ('script');
    tstScript.textContent = "TM_canaryIsAlive = true;";
    try {
        document.documentElement.appendChild (tstScript);
    }
    catch (zError) {
        console.log ("Local JS fails: " + zError);
        gbl_InlineJS_Works = false;
    }
    if (gbl_InlineJS_Works) {
        if ( ! unsafeWindow.TM_canaryIsAlive) {
            gbl_InlineJS_Works = false;
        }
    }
}

console.log (`Inline javascript ${gbl_InlineJS_Works ? "works!" : "is blocked."}`);

【讨论】:

    【解决方案2】:

    一种方法是访问页面的标题。为此,您必须发出 http 请求 Accessing the web page's HTTP Headers in JavaScript

    您还可以查看其中一些解决方案How to detect Content Security Policy (CSP)

    -- 更新 1

    这基本上是未经测试的。我针对 facebook.com 运行它

    function inlineScriptEnabled() {
      let req = new XMLHttpRequest();
      req.open('GET', document.location, false);
      req.send(null);
      let header = req.getResponseHeader('content-security-policy');
      if (!header)
        return true;
      let regex = /(^|\s)'unsafe-inline'(;|\s|$)/i; 
      return !!header.match(regex);
    }
    console.log(inlineScriptEnabled());
    

    您还应该按照此处所述在文档中搜索元标记。 https://developers.google.com/web/fundamentals/security/csp/#the_meta_tag 逻辑类似。

    【讨论】:

    • 您能否提供一个通过页面的 HTTP 标头进行 CSP 检测的工作示例?使用第一页上的解决方案,我看不到 Content-Security-Policy 标头(或任何类似的标头,例如 X-Content-Security-Policy)。
    • 这似乎只是告诉我网站本身是否配置了 CSP 标头。当我使用 uBlock Origin(Chrome 扩展程序)通过 *$inline-script,domain=stackoverflow.com 之类的过滤器阻止内联 JavaScript 时,它没有帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-10-13
    • 2019-11-06
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2011-02-16
    相关资源
    最近更新 更多