Canvas指纹隐藏实战

2022-11-14 13:57:22 浏览数 (1)

前言

前两天和隔壁做风控的同学聊天,据说他们经常使用浏览器指纹来识别和标记爬虫(当然具体的细节是不能透露的),联想到我们最近也经常遇到被风控的情况,于是就花了点时间研究下浏览器指纹相关的知识。

需要明确的是,“隐藏浏览器指纹”和“隐藏Webdriver/Selenium/Puppeteer”、“匿名浏览”都不是同一个问题。“隐藏Webdriver/Selenium/Puppeteer”的目的是告诉服务端自己不是自动化爬虫(这个似乎可以尝试用 stealth.min.js 来做);“匿名浏览”的目的是不让浏览记录在本地留下痕迹(这个可以用浏览器的匿名模式来实现);“隐藏浏览器指纹”是为了不让服务端追踪“现在的我和之前的我是同一个我”(这个是我们这次想解决的问题)。

浏览器指纹一般是通过 Javascript 能提取或计算得到的一些具有一定稳定性独特性的参数。风控的同学将这些参数做一定取舍和组合,就能得到一台浏览器的大致标识。在没有强制登陆的情况下,有了这个标识,风控的同学可以做反爬、广告的同学可以做推荐、数据的同学可以算uv等等,用处还是不小的。

常见的浏览器指纹会提取如下东西:

  1. UserAgent和平台信息
  2. 浏览器加载的字体信息
  3. 声卡指纹
  4. Canvas指纹
  5. 显示器分辨率
  6. 语言、地区时区信息
  7. CPU核数和可用内存信息
  8. 本地存储、Cookie等信息
  9. 浏览器安装的插件信息
  10. 科学计算的指纹信息
  11. IP和代理信息

可以看出来,这里有的指标稳定性比较好,比如UserAgent、分辨率、地区、语言、字体信息等,但是这些指标通常区分度不是很好。因此我们通常更喜欢用一些硬件指纹信息来进行区分。当然,为了衡量指标的这种“独特性”,Peter Eckersley 提出了用一个指标对设备唯一指纹引入的熵来衡量指标的这种特性,下面是我的设备在 coveryyourtracks 中跑出来的一些常见指标的效果:

代码语言:javascript复制
USER AGENT
Bits of identifying information: 9.04
One in x browsers have this value: 524.71
 
HTTP_ACCEPT HEADERS
Bits of identifying information: 8.96
One in x browsers have this value: 496.75
 
BROWSER PLUGIN DETAILS
Bits of identifying information: 3.25
One in x browsers have this value: 9.54
 
TIME ZONE OFFSET
Bits of identifying information: 5.26
One in x browsers have this value: 38.38
 
TIME ZONE
Bits of identifying information: 6.83
One in x browsers have this value: 114.13
 
SCREEN SIZE AND COLOR DEPTH
Bits of identifying information: 6.28
One in x browsers have this value: 77.57
 
SYSTEM FONTS
Bits of identifying information: 3.92
One in x browsers have this value: 15.12
 
ARE COOKIES ENABLED?
Bits of identifying information: 0.13
One in x browsers have this value: 1.09
 
LIMITED SUPERCOOKIE TEST
Bits of identifying information: 1.41
One in x browsers have this value: 2.67
 
HASH OF CANVAS FINGERPRINT
Bits of identifying information: 9.73
One in x browsers have this value: 847.61
 
HASH OF WEBGL FINGERPRINT
Bits of identifying information: 9.75
One in x browsers have this value: 862.69
 
WEBGL VENDOR & RENDERER
Bits of identifying information: 8.5
One in x browsers have this value: 362.9
 
DNT HEADER ENABLED?
Bits of identifying information: 0.95
One in x browsers have this value: 1.93
 
LANGUAGE
Bits of identifying information: 7.47
One in x browsers have this value: 176.69
 
PLATFORM
Bits of identifying information: 3.11
One in x browsers have this value: 8.62
 
TOUCH SUPPORT
Bits of identifying information: 0.76
One in x browsers have this value: 1.7
 
AD BLOCKER USED
Bits of identifying information: 0.15
One in x browsers have this value: 1.11
 
AUDIOCONTEXT FINGERPRINT
Bits of identifying information: 5.92
One in x browsers have this value: 60.59
 
CPU CLASS
Bits of identifying information: 0.12
One in x browsers have this value: 1.09
 
HARDWARE CONCURRENCY
Bits of identifying information: 1.93
One in x browsers have this value: 3.82
 
DEVICE MEMORY (GB)
Bits of identifying information: 2.31
One in x browsers have this value: 4.96

其中,“Bits of identifying information” 表示这个指标对我的浏览器引入的唯一性的位数,这个位数越大,越表明这个指标更能区分我的浏览器和其他的浏览器;“One in x browsers have this value” 表示平均多少个浏览器的这个指标和我的浏览器的这个指标一样,这个数越大,越表明这个指标的区分度好。

显然,从这里看,区分度最高的指标就是 "UserAgent" , "WebGL指纹" 和 "Canvas 指纹" 。那这些指纹是怎么 work 的呢?例如Canvas指纹,其实就是由于Web 浏览器使用的图像处理引擎、图像导出选项、压缩级别、操作系统的字体,抗锯齿和亚像素渲染算法等的不同,导致画出来的图片在像素级别存在的微小但稳定的差距。这样我们就可以拿这个生成图片的校验和或算一个Hash作为他的指纹。

指纹检测

目前业内较为知名的浏览器指纹检测网站大概有下面这三个:

  1. https://fingerprintjs.github.io/fingerprintjs/
  2. http://f.vision/
  3. https://coveryourtracks.eff.org/

第一个是最常见的浏览器指纹生成项目,之前某手用过一段时间,后来好像不用了,可以作为入门项目来看。

第二个是一个进阶的在线检测指纹的网站,检测点更全,也有一定的反伪造能力。

第三个是 Peter Eckersley 实验用的检测指纹的网站,教育意义更明显,也有一定的反伪造能力。

有矛就有盾,作为(爬虫)普通用户,我们显然不想让服务端跟踪我们的操作路径,但又不想用 Tor 浏览器。因此我们就要想一些对付这些指纹检测的办法。下面就是我做的一些尝试。

Fingerpintjs指纹

指纹生成算法

首先我们先看下 fingerprintjs 检测 Canvas 指纹的核心代码,作为我们首先需要绕过的目标:

代码语言:javascript复制
function makeTextImage(canvas, context) {
    // Resizing the canvas cleans it
    canvas.width = 240;
    canvas.height = 60;
    context.textBaseline = 'alphabetic';
    context.fillStyle = '#f60';
    context.fillRect(100, 1, 62, 20);
    context.fillStyle = '#069';
    // It's important to use explicit built-in fonts in order to exclude the affect of font preferences
    // (there is a separate entropy source for them).
    context.font = '11pt "Times New Roman"';
    // The choice of emojis has a gigantic impact on rendering performance (especially in FF).
    // Some newer emojis cause it to slow down 50-200 times.
    // There must be no text to the right of the emoji, see https://github.com/fingerprintjs/fingerprintjs/issues/574
    // A bare emoji shouldn't be used because the canvas will change depending on the script encoding:
    // https://github.com/fingerprintjs/fingerprintjs/issues/66
    // Escape sequence shouldn't be used too because Terser will turn it into a bare unicode.
    var printedText = "Cwm fjordbank gly "   String.fromCharCode(55357, 56835) /* 


	

0 人点赞