如何检测浏览器的扩展?

3

我想检测用户浏览器上是否安装了某个扩展。

我尝试了以下代码:

var detect = function(base, if_installed, if_not_installed) {
    var s = document.createElement('script');
    s.onerror = if_not_installed;
    s.onload = if_installed;
    document.body.appendChild(s);
    s.src = base + '/manifest.json';
}
detect('chrome-extension://' + addon_id_youre_after, function() {alert('boom!');});

如果浏览器已安装扩展程序,则会出现以下错误:

资源必须在web_accessible_resources清单键中列出,以便由扩展程序外的页面加载

GET chrome-extension://invalid net::ERR_FAILED

如果没有安装扩展程序,则会出现不同的错误。

GET chrome-extension://addon_id_youre_after/manifest.json net::ERR_FAILED

这是我得到的错误的图像:The errors I am getting from the fiddle 我试图捕获错误(fiddle)
try {
  var s = document.createElement('script');
    //s.onerror = window.setTimeout(function() {throw new Error()}, 0);
    s.onload = function(){alert("installed")}; 
    document.body.appendChild(s);
    s.src = 'chrome-extension://gcbommkclmclpchllfjekcdonpmejbdp/manifest.json';
} catch (e) {
  debugger;
  alert(e);
}

window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
    alert('Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber
    + ' Column: ' + column + ' StackTrace: ' +  errorObj);
}

到目前为止,我还无法捕捉到错误...
非常感谢您提供的任何帮助。


啊,这是一个有趣的想法。我看到现有的答案利用XMLHttpRequest并检查响应是否出错。 - wOxxOm
@wOxxOm,这就是我正在尝试做的事情,但出于某种原因我无法捕获错误。请看更新后的问题,我添加了一张图片。 - Offir
@wOxxOm,我认为这不会起作用,因为chrome-extension:不是这样工作的,它就像浏览器内部请求。 - Offir
好的,现在我看到这个问题确实非常不同(如何捕获这个特定的错误)。我会取消重复并稍微编辑一下问题,让它更加突出。 - Xan
这里是对这个问题的答案,附加说明为什么它不起作用(剧透:因为Google不想让它起作用)。 - Xan
显示剩余6条评论
2个回答

3
第一个错误来自Chrome,直接注入到控制台中,无法被你捕获(正如你所注意到的)。 GET错误来自网络堆栈。在两种情况下,Chrome都拒绝加载并模拟网络错误 - 你可以通过在元素本身上使用onerror处理程序来捕获,但不能在window.onerror处理程序中捕获。引用,强调我的话:

当资源(例如<img><script>)未能加载时,会在发起加载的元素上触发使用接口Event的错误事件,并调用元素上的onerror()处理程序。 这些错误事件不会冒泡到window对象,但(至少在Firefox中)可以使用单个捕获的window.addEventListener处理。

这里有一个例子,至少可以检测到网络错误。请注意,您仍然无法“捕获”它们,即防止它们显示在控制台中。当Google Cast扩展(暴露资源的扩展)使用它作为检测方法时,它曾经是一个尴尬问题的来源
s.onload = function(){alert("installed")}; 
s.error = function(){alert("I still don't know")};

注意,你无法区分这两者。在内部,Chrome将其中一个请求重定向到chrome-extension:// invalid,但这样的重定向对于您的代码是透明的:无论是加载资源(如您所做的)还是使用XHR。即使是新的Fetch API,它被认为可以更好地控制重定向,也无法帮助,因为它不是HTTP重定向。它只得到了一个没有信息的网络错误。
因此,您无法检测扩展程序是否未安装或已安装但未公开资源。
请理解这是有意的。您提到的方法曾经有效 - 您可以按名称获取任何资源。但这是一种指纹浏览器的方法 - 谷歌明确称之为“恶意”,并希望防止这种情况发生。
因此,在Chrome 18中引入了web_accessible_resources模型(早在2012年8月),以保护扩展免受嗅探 - 要求显式声明暴露的资源。引用,重点在我身上:
在清单版本2之前,扩展内的所有资源都可以从Web上的任何页面访问。这使得恶意网站可以识别用户已安装的扩展,或利用已安装扩展中的漏洞(例如XSS漏洞)。仅限于明确打算公开的资源可用性有助于最小化可用攻击面并保护用户的隐私。

谷歌正在积极对抗指纹识别,只有合作的扩展程序才能被可靠地检测到。可能存在特定于扩展程序的黑客攻击 - 例如特定的DOM更改、请求拦截或可获取的公开资源 - 但没有通用方法,扩展程序可以随时更改它们的“可见签名”。我在这个问题中解释了这一点: Javascript check if user has a third party chrome extension installed,但我希望您能更好地理解这个原因。

总之,如果您确实找到了一种公开任意扩展程序进行指纹识别的通用方法,那么这将被视为Chrome中的恶意行为和隐私漏洞。


-1
让您的Chrome扩展程序在页面上查找一个具有非常特定ID的特定DIV或其他元素。
例如:-
<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>

1
你可以使用chrome.management.getAll()获取已安装扩展的列表,其中包含比ID更多的信息。 - Sukhjinder Singh
1
我认为这是一个扩展开发者的解决方案。 - Offir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接