检测代码是否作为Chrome扩展程序运行

时间:2011-09-21 22:06:29

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

我正在使用一些需要作为页面运行的代码,如果它作为Chrome Extension运行,我希望能够做更多的事情。我正在使用的是:

<script>
if (chrome && chrome.extension) {
    // extension stuff
}
</script>

这似乎很不错capability detection。使用用户代理字符串会给我带来麻烦,因为无论上下文(网页与扩展名)如何都是一样的。

问题:是否还有其他更可靠的技术可用于检测Chrome扩展程序中是否有一段代码正在运行?

更新:我想知道是否可以将某些内容放入我的manifest.json文件中,然后我可以回读。请注意,我正在处理的扩展不是一直运行的持久性事物,它是一个在单个窗口或浏览器选项卡中运行的内容应用程序,无需与其他窗口或选项卡或其他任何内容交互

7 个答案:

答案 0 :(得分:23)

这里有很多复杂的答案,而您可以通过检查chrome.runtime.id的存在和非空虚来轻松检测您是否在Chrome扩展程序中运行:

if (window.chrome && chrome.runtime && chrome.runtime.id) {
    // Code running in a Chrome extension (content script, background page, etc.)
}

答案 1 :(得分:4)

务实地说这是一个很好的方法。从理论上讲(不确定这是否相关,例如可能提供漏洞),它可以非常容易地被欺骗。我想这取决于你的背景是多么相关。

这是一个稍微强烈的想法:

if (chrome &&
    chrome.windows &&
    chrome.windows.get &&
    typeof chrome.windows.get === 'function' &&
    chrome.windows.get.toString() === 'function get() { [native code] }')

这个想法和你的想法一样,虽然它稍微强一点,因为AFAIK有一个对象是一个函数并且它的toString()值具有该值是不可能的,因为它不是有效的语法,所以即使试图欺骗它除非您更改了本机代码(这需要完全不同级别的黑客),否则该值将无效。

不要随便记住,检查这样的事情是否需要权限,但我希望这个想法很明确。

<强>更新

我刚刚意识到,通过别名现有函数,可以欺骗“本机代码”语法理念。 E.g。

var FakeFn = Object.create;
FakeFn.toString(); // "function create() { [native code] }"

但是可以通过仔细选择我们使用的函数来处理,因为名称出现在字符串中。 get可能过于常见,但如果我们采用仅在Chrome扩展中实现的模糊函数名称(如captureVisibleTab chrome.tabs.captureVisibleTab),它仍然是一个非常便携的解决方案,因为基本检查代码可以被其他本地用户代码欺骗,事先已知浏览器没有实现具有此名称的任何本机函数,因此它在所有浏览器中仍然是安全的并且具有所有用户代码。

<强>更新

正如@Mathew指出的那样,这个想法是可以实现的(虽然看似只是恶意)。我认为我可以通过与Function.prototype.toString进行比较来修补问题,但认为即使可以通过对原始toString方法进行别名并创建一个新的方法来愚弄,因为某些函数会返回假字符串,而其他函数会返回原始字符串。

总之,我的想法比原版略强,因为它几乎可以排除所有无意碰撞的机会(略高于OP的想法),但当然我无法防范恶意攻击可能是。

答案 2 :(得分:2)

我知道这已经过时了,但我想我会提供另一种选择。您可以将另一个javascript文件添加到chrome扩展,因此它包含两个.js文件。 manifest.json会有:

"js": ["additionalscript.js", "yourscript.js"]

additionalscript.js可以简单地声明一个变量var isextension = true。 yourscript.js可以查看typeof isextension != 'undefined'

但也许是一个更有趣的例子,它可以宣告

var adminpassword='letmein'

现在yourscript.js在扩展程序中运行时只能访问adminpassword。

(如果插件位于可能受到攻击的计算机上,您当然不会在脚本文件中嵌入密码)

答案 3 :(得分:2)

我需要类似的东西。

但我并不需要关心试图欺骗代码的网站。

const SCRIPT_TYPE = (() => {
    if (chrome && chrome.extension && chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() === window) {
        return 'BACKGROUND';
    } else if (chrome && chrome.extension && chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() !== window) {
        return 'POPUP';
    } else if (!chrome || !chrome.runtime || !chrome.runtime.onMessage) {
        return 'WEB';
    } else {
        return 'CONTENT';
    }
})();

上面应该检测4个场景

  • javascript在后台页面中运行
  • javascript在弹出页面/ iframe中运行
  • javascript在上下文脚本中运行
  • javascript直接在网站上运行

答案 4 :(得分:1)

我注意到在Chrome中,无法删除chrome对象,即全局窗口对象的属性。如果是用户定义属性删除操作成功。所以你可以用这种方式测试:

var isRunningInExtension = (!(delete window.chrome) && chrome.extension) ? 
                           true : false;

更新: 上面的行并不能保证代码在chrome扩展中运行。每个人都可以使用“扩展”属性创建一个名为“chrome”的对象,然后冻结/密封该对象 - 这样做就足以通过检查,并且您的代码在chrome扩展中运行的结果不正确。

确保您在扩展程序中运行代码,您必须在运行任何javascript之前测试全局chrome对象 - 这样您就可以保证在测试之前不会创建假的chrome对象。

一种可能的解决方案是使用iframe - 在我下面的示例中,我使用iframe的sandbox属性来指示iframe不执行任何脚本(甚至脚本标记中包含的脚本) - 这样我就可以确保没有脚本能够修改全局window.chrome对象。

(function() {
  var isChromeExtension = (function () {
    var contentWindow,
        iframe = document.createElement("iframe"),
        isChromeExtension;
    // test for sandbox support. It is supported in most recent version of Chrome
    if ("sandbox" in iframe) {
      try {
        iframe.sandbox = "allow-same-origin";
        iframe.src=location.href;
        iframe.style="display: none";
        document.body.appendChild(iframe);
        contentWindow = iframe.contentWindow;
        isChromeExtension = !!(contentWindow.chrome && contentWindow.chrome.extension);
        document.body.removeChild(iframe);
      } catch(e) {}
    }
    return isChromeExtension;
  }());
}());

结果可能是:

  • true - 如果代码在Chrome扩展程序中运行
  • false - 如果代码未在Chrome扩展程序中运行
  • undefined - 如果浏览器不支持iframe沙箱或测试期间发生错误

答案 5 :(得分:1)

Chrome不提供任何直接API来检查在扩展程序弹出窗口或Chrome页面视图中运行的应用程序的运行状态。但是,一个间接技巧可以工作,我们可以匹配扩展主体分辨率等于或小于CSS中指定的(在这种情况下,扩展弹出窗口将打开)或大于(在这种情况下,网页视图将是打开)。

答案 6 :(得分:0)

要检测Chrome应用和扩展程序,请使用:

chrome.app.getDetails()
相关问题