不用 cookie 我也能追踪你!

Author Avatar
Pang Jian 3月 09, 2015
总字数:653 预计阅读:2 min
  • 在其它设备中阅读本文章

抱歉起了这么个“吸引人的”标题,但我不是标题党。最近由于工作上的一些事情,涉及到识别、追踪设备的项目来了几个,从一篇论文《The Web Never Forgets》无意间又发现了这个技术。查阅了一些资料。做了个小 Demo 应用到了本博客上。对!你没听错,本页面在追踪你。不过也没那么可怕。看看本站的 Visitor Info 模块,它可能在屏幕右侧也可能在最底下。这个模块会知道你是否之前访问过本站,并且结合了上一篇博文 基于 Firebase 的 Hexo 博客实时访问数统计 中提到的访问数统计,做到了记录每一位访问者的访问次数。即使你关闭了 cookie。^ _ ^

原理

这个技术的原理是这样的,网站使用了一个 HTML5 的标签 canvas。在绘制 canvas 的时候,不同的机器、平台、浏览器绘制出的图片在哈希层面是不同且独一无二的,利用这个特性可以追踪这个用户。
技术原理是这样的,但是为什么每一个设备、浏览器绘制的图像是不同的我不太清楚,有兴趣可以参考文章最后的链接。

实现

首先绘制一个canvas

        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var txt = 'http://pangjian.info';
        ctx.textBaseline = "top";
        ctx.font = "14px 'Arial";
        ctx.textBaseline = "pangjian";
        ctx.fillStyle = "#f60";
        ctx.fillRect(125, 1, 62, 20);
        ctx.fillStyle = "#069";
        ctx.fillText(txt, 2, 15);
        ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
        ctx.fillText(txt, 4, 17);

然后通过 canvas.toDataURL() 获取图片的 base64 编码,png 图片被划分成很多块,每块的最后 32bit 数据是 crc 校验值,提取出这个值就可以用来当做浏览器指纹。

        var b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
        var bin = atob(b64);
        var crc = _t.bin2hex(bin.slice(-16, -12));

字节转换成 16 进制方法

    bin2hex: function(s) {
        var i, l, o = '',
            n;
        s += '';
        for (i = 0, l = s.length; i < l; i++) {n = s.charCodeAt(i).toString(16);
            o += n.length < 2 ? '0' + n : n;
        }
        return o;
    }

当然你查看本页的源代码可以看到一个文件 -canvasFringerprint.js。那是完整代码。
我提取出这个指纹以后,在 Firebase 上为每一个指纹设置了一个计数器,这样就实现了为每一位访问者记录访问次数。
效果如下:
visitor counter
你可以试试开启浏览器的隐身模式,或者删除全部 cookie。再刷新一下这个页面,看看是不是他还记得你?

链接

https://securehomes.esat.kuleuven.be/~gacar/persistent/the_web_never_forgets.pdf
https://www.browserleaks.com/canvas#how-does-it-work

Documentation licensed under CC BY-SA 4.0.
本文链接:https://www.pangjian.me/2015/03/09/track-u-without-cookie/