对于一些电商或者金融网站来说,怎么阻挡薅羊毛的蝗虫和恶意搞事情的熊孩子是很头疼的事情。
防止批量注册或下单等敏感操作很关键,所以识别出真实的、唯一的浏览器就很重要了。
对于使用无头浏览器来模拟用户操作的检测,可以参考我之前写的《无头浏览器异闻录》一文。
常用的开源浏览器指纹搜集程序有 fingerprintjs,浏览器追踪有 evercookie。
下面是一些研究时找到的部分其他向量,比较杂,仅供参考。
(文中提到的浏览器均在 Windows 平台下测试,Chrome 版本为 58.0.3029.96,Firefox 版本为 53.0,IE 版本为 11.296.15063)
爬虫特征
Bot-Buster
真实浏览器第一次访问网站一定会请求网站图标(favicon.ico
)。
HSTS Super Cookie
HTTP Strict Transport Security (HSTS)
用来保证网站始终使用 HTTPS 安全连接。
如果某个网站启用了 HSTS,浏览器会记住该网站,下次访问时会自动重定向到 HTTPS。
但恶意网站可以通过控制一组网址是否开启 HSTS 来生成类似 10100101011
的独特数字序列(开启为 1,关闭为 0),
从而借此给每一个用户独有的 ID 并跟踪用户。
HSTS Super Cookie 最初还可以传递到隐身模式,经测试目前 Chrome、FireFox、IE 的最新版本已经修复,但 Safari 仍未修复。
demo:http://www.radicalresearch.co.uk/lab/hstssupercookies/
解释:Web 前端利用 HSTS 漏洞的超级 Cookie (HSTS Super Cookie)
Geo API
HTML5 获取地理位置:navigator.geolocation
API 的数据来源可能是 GPS、IP 地址、RFID、WiFi、蓝牙 MAC 地址、GSM/CDMA 卡 ID 等,
所以如果是非移动端,数据可能通过IP等其他方式获得,偏差会有点大。
WebRTC
用来支持网页浏览器进行实时语音对话或视频对话的 API。
扫描内网,获得真实 IP (https://diafygi.github.io/webrtc-ips/)
最新的 Chrome 上已不可用,Firefox 可以。
Console
检查浏览器 Console 是否打开,普通用户不会使用 Console。如果打开可能是在调试页面代码。
相关讨论:Detect all browser console open or not
var checkStatus;
var element = new Image();
// var element = document.createElement('any');
element.__defineGetter__('id', function() {
checkStatus = 'on';
});
setInterval(function() {
checkStatus = 'off';
console.log(element);
console.clear();
document.querySelector('#devtool-status').innerHTML = checkStatus;
}
demo:https://jsfiddle.net/evnrorea/
隐身浏览
Chromium 内核浏览器下的隐身模式追踪
需要一个 chrome 域的跨站漏洞配合。
Detecting if a browser is using Private Browsing mode
隐私模式下 IE 和 Firefox 无法使用 IndexDB
,Safari 无法使用 LocalStorage
。
Chrome 可通过 RequestFileSystem
检查。
function main() {
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fs) {
result.textContent = "check failed?";
return;
}
fs(window.TEMPORARY, 100, function(fs) {
result.textContent = "it does not seem like you are in incognito mode";
}, function(err) {
result.textContent = "it seems like you are in incognito mode";
});
demo:http://jsfiddle.net/w49x9f1a/
Service Worker
Push API 用于根据用户的唯一标识进行主动消息推送的。具体用法:PushManager.getSubscription()
就像文档中所说,它最后会返回一个 PushSubscription 对象。
这个对象中的 endpoint 就是浏览器 Push 服务器来寻找客户端的依据,它可以直接拿来当设备的唯一标识符。
缺点:Safari 和 IE 不支持,手机浏览器大部分也不支持。
Service Worker 的浏览器兼容状态见 Can I use Service Workers
AudioContext
和 Canvas 类似,不同浏览器和操作系统的 Audio 渲染特征也不同。
目前还有使用超声波跨设备追踪用户的例子。(234 Android Applications Are Currently Using Ultrasonic Beacons to Track Users)
Battery API
HTML5 获取电池状态:navigator.getBattery
可以判断是否是移动设备,根据耗电规律可以推测用户行为(看电影、游戏等)
demo:http://pazguille.github.io/demo-battery-api/
Etag
Etag 用于验证 Web 缓存,如果资源的内容没有发生改变,Web 服务器就不需要发送一个完整的响应。
Etag 实际上可以起到 Cookie 的作用,恶意网站只需生成 1*1 大小的 gif 图片,在浏览器访问时返回一个用于标识用户的 Etag,
接下来用户每次访问含有该图片的页面时浏览器都会自动发送含有该 Etag 的 If-None-Match
HTTP 头。
Etag 无法用常规手段清除,只能删除浏览器缓存。
与之相似的还有 Last-Modified
。
demo:http://lucb1e.com/rp/cookielesscookies/
参考
Technical analysis of client identification mechanisms
Tracking without cookies
Tracking survey
Online Tracking: A 1-million-site Measurement and Analysis
(Cross-)Browser Fingerprinting via OS and Hardware Level Features
是否可能从流量层面(tcp/ip)来抓取一些设备的特征呢? 看了一篇关于http/2的被动指纹的paper..但是http/2不兼容低版本的浏览器.
流量层面成本太大了…
http://t.cn/RnqxdcC 找到一个有意思的.
有点类似这个 https://github.com/jbtronics/CrookedStyleSheets ,也是 CSS 实现的