我想我可以通过 Javascript 检测浏览器本身内部的 Tor 浏览器吗?
Can I detect Tor Browser inside the browser itself, via Javascript I suppose?
如果浏览器是 Tor 浏览器,我想禁用我正在构建的 Web 应用程序的某些功能。我可以在浏览器内部(客户端,而不是服务器端)查明浏览器是否是 Tor 浏览器吗?
我更喜欢不发出任何 HTTP 请求来匹配浏览器 IP 与 Tor 出口节点的解决方案。
背景:在我的例子中,Tor 浏览器弹出一个对话框,询问用户 "Should Tor Browser allow this website to extract HTML5 canvas image data?",因为 Tor 浏览器说,canvas 图像数据可用于唯一标识浏览器。
更新: 阅读以下答案后:也许对我来说最好的解决方案是在服务器端保留 Tor 出口节点列表(最新列表,定期刷新),当浏览器加载页面时,我在 <script>
标记中设置一个变量,如果浏览器的 IP 匹配这样一个出口节点:var isProbablyTorBrowser = true
。然后客户端,不需要额外的请求,也不需要复杂的逻辑。
检测tor的"official"方法是检查用户的IP地址,看看它是否是tor出口节点。为此,Tor 运行 TorDNSEL。
这是 PHP TorDNSEL 查找的实现,来自 Irongeek
的教程
function IsTorExitPoint(){
if (gethostbyname(ReverseIPOctets($_SERVER['REMOTE_ADDR']).".".$_SERVER['SERVER_PORT'].".".ReverseIPOctets($_SERVER['SERVER_ADDR']).".ip-port.exitlist.torproject.org")=="127.0.0.2") {
return true;
} else {
return false;
}
}
function ReverseIPOctets($inputip){
$ipoc = explode(".",$inputip);
return $ipoc[3].".".$ipoc[2].".".$ipoc[1].".".$ipoc[0];
}
如果您不使用 PHP,您应该仍然能够相对轻松地适应它。
另一种检测 Tor 的方法是让脚本每半小时左右下载一次 Tor 出口节点列表,然后根据该列表检查每个用户的 IP 地址。不过,这可能不太可靠,因为并非所有出口节点都已发布。在 dan.me.uk.
上有一个您可以使用的列表和说明
编辑:由于您更新了问题,因此第二个选项(您在本地托管的列表)将更可取。
没有可靠的方法来检测 TOR 浏览器...这就是该浏览器的目标。如果你找到了一个可靠的方法,其他人也有可能找到它,告诉 TOR 开发人员然后他们关闭它。
例如所有 TOR 浏览器捆绑报告虚假但合理的用户代理。当前发行版本,例如说它是 Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0
不管你实际使用什么 OS。
您可以应用一些启发式方法以一定的概率检测到 TOR 浏览器,但也会产生一些误报...
- 检查用户代理。 TOR 浏览器将在某个 OS 上报告最新的 Firefox ESR,目前是 Windows 7 32 位(但一些用户可能已经再次更改,其他用户可能只是使用 ESR 版本而不是 TOR 浏览器)
- 插件已禁用,因此
navigator.plugins
将为空(但某些用户可能再次重新启用了插件)。
- 等等
- 实际检测浏览器uses the TOR network。
当然,您必须及时更新支票,因此需要大量的维护工作。
就个人而言,鉴于检测结果不尽如人意、维护负担和用户体验改进非常有限,我根本不会尝试以不同方式处理 TOR 浏览器。
Tor 浏览器并非设计为不可检测(这是不可能做到的)。相反,它的设计使所有副本彼此无法区分:您无法严格通过 browser fingerprinting.
来跟踪浏览器从一个站点到另一个站点,或从一次访问到另一次访问。
这给了它自己独特的指纹。截至目前,
的浏览器
- 拥有
Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0
的用户代理
- 具有与浏览器 window 大小匹配的屏幕分辨率(特别是如果该大小为 1000x800)
- 时区为“0”(格林威治标准时间)
- 没有插件(
navigator.plugins
为空)
应该是TBB浏览器。下一个 ESR 版本的 Firefox 发布时,User-Agent 字符串可能会更改,最有可能 Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/38.0
.
屏幕 resolution/browser window 单独匹配可以唯一标识 TBB:即使在全屏模式下,window 高度与 Firefox 中的屏幕高度之间存在一个像素的差异。
通过firefox资源包可以查看。
Firefox 使用 resource:// URI 方案从内部模块和扩展调用磁盘资源。
但其中一些资源也可能包含在任何网页中并通过脚本标签执行。 Mozilla 开发人员并未将资源视为指纹向量,尽管事实上其中一些资源可以揭示用户不希望看到的内容。例如,内置首选项文件的差异清楚地表明您正在使用 Windows 或 Linux 或 Mac,即使您使用的是 Tor 浏览器。
可能有一个比较靠谱的方法。当您尝试使用 canvas 对其进行 Base64 编码时,请检查它 returns 是否为空白(白色)图像。
When you do so an notification is shown.
无论什么用户选择JS returns 一个白色图像。因此,您可以尝试对非白色图像进行 base64(<-- 这是一个动词 ;)),然后检查是否返回了白色 base64 图像。
更新。
这是我为自己制作的示例。对我来说,检测我是否有权访问图像很重要,但它可以以某种方式用于 Tor 检测。
UPD2。
甚至可能没有显示通知,如下面的代码片段所示。可能是因为它在 iframe 中 运行。
function isTorBrowser() {
var img = document.createElement("img");
// Creates a black 1x1 px image
img.src = 'data:image/png;base64,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';
var canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
var ctx = canvas.getContext("2d");
var imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);
return imagedata.data[0] == 255
&& imagedata.data[1] == 255
&& imagedata.data[2] == 255
&& imagedata.data[3] == 255;
}
document.getElementById('tor-browser-test').innerHTML = isTorBrowser() ? 'Is Tor' : 'Not Tor';
<div id="tor-browser-test"></div>
如果浏览器是 Tor 浏览器,我想禁用我正在构建的 Web 应用程序的某些功能。我可以在浏览器内部(客户端,而不是服务器端)查明浏览器是否是 Tor 浏览器吗?
我更喜欢不发出任何 HTTP 请求来匹配浏览器 IP 与 Tor 出口节点的解决方案。
背景:在我的例子中,Tor 浏览器弹出一个对话框,询问用户 "Should Tor Browser allow this website to extract HTML5 canvas image data?",因为 Tor 浏览器说,canvas 图像数据可用于唯一标识浏览器。
更新: 阅读以下答案后:也许对我来说最好的解决方案是在服务器端保留 Tor 出口节点列表(最新列表,定期刷新),当浏览器加载页面时,我在 <script>
标记中设置一个变量,如果浏览器的 IP 匹配这样一个出口节点:var isProbablyTorBrowser = true
。然后客户端,不需要额外的请求,也不需要复杂的逻辑。
检测tor的"official"方法是检查用户的IP地址,看看它是否是tor出口节点。为此,Tor 运行 TorDNSEL。
这是 PHP TorDNSEL 查找的实现,来自 Irongeek
的教程function IsTorExitPoint(){
if (gethostbyname(ReverseIPOctets($_SERVER['REMOTE_ADDR']).".".$_SERVER['SERVER_PORT'].".".ReverseIPOctets($_SERVER['SERVER_ADDR']).".ip-port.exitlist.torproject.org")=="127.0.0.2") {
return true;
} else {
return false;
}
}
function ReverseIPOctets($inputip){
$ipoc = explode(".",$inputip);
return $ipoc[3].".".$ipoc[2].".".$ipoc[1].".".$ipoc[0];
}
如果您不使用 PHP,您应该仍然能够相对轻松地适应它。
另一种检测 Tor 的方法是让脚本每半小时左右下载一次 Tor 出口节点列表,然后根据该列表检查每个用户的 IP 地址。不过,这可能不太可靠,因为并非所有出口节点都已发布。在 dan.me.uk.
上有一个您可以使用的列表和说明编辑:由于您更新了问题,因此第二个选项(您在本地托管的列表)将更可取。
没有可靠的方法来检测 TOR 浏览器...这就是该浏览器的目标。如果你找到了一个可靠的方法,其他人也有可能找到它,告诉 TOR 开发人员然后他们关闭它。
例如所有 TOR 浏览器捆绑报告虚假但合理的用户代理。当前发行版本,例如说它是 Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0
不管你实际使用什么 OS。
您可以应用一些启发式方法以一定的概率检测到 TOR 浏览器,但也会产生一些误报...
- 检查用户代理。 TOR 浏览器将在某个 OS 上报告最新的 Firefox ESR,目前是 Windows 7 32 位(但一些用户可能已经再次更改,其他用户可能只是使用 ESR 版本而不是 TOR 浏览器)
- 插件已禁用,因此
navigator.plugins
将为空(但某些用户可能再次重新启用了插件)。 - 等等
- 实际检测浏览器uses the TOR network。
当然,您必须及时更新支票,因此需要大量的维护工作。
就个人而言,鉴于检测结果不尽如人意、维护负担和用户体验改进非常有限,我根本不会尝试以不同方式处理 TOR 浏览器。
Tor 浏览器并非设计为不可检测(这是不可能做到的)。相反,它的设计使所有副本彼此无法区分:您无法严格通过 browser fingerprinting.
来跟踪浏览器从一个站点到另一个站点,或从一次访问到另一次访问。这给了它自己独特的指纹。截至目前,
的浏览器- 拥有
Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0
的用户代理
- 具有与浏览器 window 大小匹配的屏幕分辨率(特别是如果该大小为 1000x800)
- 时区为“0”(格林威治标准时间)
- 没有插件(
navigator.plugins
为空)
应该是TBB浏览器。下一个 ESR 版本的 Firefox 发布时,User-Agent 字符串可能会更改,最有可能 Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/38.0
.
屏幕 resolution/browser window 单独匹配可以唯一标识 TBB:即使在全屏模式下,window 高度与 Firefox 中的屏幕高度之间存在一个像素的差异。
通过firefox资源包可以查看。
Firefox 使用 resource:// URI 方案从内部模块和扩展调用磁盘资源。
但其中一些资源也可能包含在任何网页中并通过脚本标签执行。 Mozilla 开发人员并未将资源视为指纹向量,尽管事实上其中一些资源可以揭示用户不希望看到的内容。例如,内置首选项文件的差异清楚地表明您正在使用 Windows 或 Linux 或 Mac,即使您使用的是 Tor 浏览器。
可能有一个比较靠谱的方法。当您尝试使用 canvas 对其进行 Base64 编码时,请检查它 returns 是否为空白(白色)图像。 When you do so an notification is shown.
无论什么用户选择JS returns 一个白色图像。因此,您可以尝试对非白色图像进行 base64(<-- 这是一个动词 ;)),然后检查是否返回了白色 base64 图像。
更新。 这是我为自己制作的示例。对我来说,检测我是否有权访问图像很重要,但它可以以某种方式用于 Tor 检测。
UPD2。 甚至可能没有显示通知,如下面的代码片段所示。可能是因为它在 iframe 中 运行。
function isTorBrowser() {
var img = document.createElement("img");
// Creates a black 1x1 px image
img.src = 'data:image/png;base64,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';
var canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
var ctx = canvas.getContext("2d");
var imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);
return imagedata.data[0] == 255
&& imagedata.data[1] == 255
&& imagedata.data[2] == 255
&& imagedata.data[3] == 255;
}
document.getElementById('tor-browser-test').innerHTML = isTorBrowser() ? 'Is Tor' : 'Not Tor';
<div id="tor-browser-test"></div>