zhengyijun
zhengyijun

六朝何事,只成门户私计。

一点设想:以canvas指纹应对滥用马甲问题

本文是给站方@Matty 的一些技术参考,或许能减轻matters个别用户反复注册新号来扰乱秩序的问题。

文章的灵感来自这里,有个用户注册了很多小号在评论区骂人:

不懂计算机的人是幸福的,因为他们不知道世界的可怕之处

这位说得对,只封ip是不够的。正好我最近比较闲,所以写篇文章向大家介绍一种即使用了VPN隐藏ip,甚至切到小号、开启隐私模式,依然能对用户进行唯一标识的技术。canvas指纹是“浏览器指纹”的一种,也就是说它只能确定“对方是不是来自同一电脑上的同一浏览器”,仅凭这种技术,无法确定“对方的现实身份是什么”,应当与matters的理念不冲突。

目前canvas指纹已经得到了广泛应用,据我所知,淘宝就用了canvas指纹识别用户,所以技术上完全可行。

canvas指纹是什么?

canvas的直译是“画布”,是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素。通过调用js脚本,可以让浏览器自己在网页中绘制出图形。详细的使用方法可见:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial。不过作为本文的读者不必了解那么多,只知道canvas能够在网页上绘制图形即可。

canvas和普通网页图片的区别在哪里?可以这样理解:普通的网页图片放在服务器上,当用户需要查看图片的时候,服务器就把图片发给客户端。如果大家使用不同的电脑访问同一张图片,得到的图片是相同的。而canvas图片只是一系列绘图的“指令”,服务器告诉客户端“怎么画”,具体的绘画工作由客户端完成。简单概括就是:普通的网页图片是已经确定好的,而canvas是你的浏览器临时画出来的。

两个不同的人,即使种族相同、甚至父母相同,指纹也不同。电脑也是如此:两台电脑即使品牌、操作系统、浏览器等等完全相同,电脑和电脑之间也会有细微的差别。反映在canvas上,导致了即使两台电脑收到了相同的“绘图指令”,画出来的图案也不相同。但是让同一台电脑反复执行同样的绘画指令,得到的图案是完全相同的。

大家可以在:https://browserleaks.com/canvas看看自己的canvas指纹,Uniqueness一项通常可以达到99.9%以上。

示例项目:

思路:在页面上画一个用户肉眼看不到的canvas,用toDataURL获取图案的特征值,去掉开头相同的部分,得到一个特征字符串。特征字符串太长,不好肉眼比对,所以又做了一遍哈希,得到最终的canvas指纹。算出指纹后,以alert弹出。

给新手的指引:新建一个文本文档,把我的代码粘贴进去,保存后把文件扩展名从txt改为html,然后用浏览器打开,点击按钮。可以看到,开不开隐私模式,都不影响canvas指纹的值。

canvas指纹的示例代码(严格来说不能算是我写的,我只是把不同人的代码拼到一起而已,码农日常啦):

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>canvas model</title>
</head>

<body>
    <script>
        /**
         * Calculate a 32 bit FNV-1a hash
         * Found here: https://gist.github.com/vaiorabbit/5657561
         * Ref.: http://isthe.com/chongo/tech/comp/fnv/
         *
         * @param {string} str the input value
         * @param {boolean} [asString=false] set to true to return the hash value as 
         *     8-digit hex string instead of an integer
         * @param {integer} [seed] optionally pass the hash of the previous chunk
         * @returns {integer | string}
         */
        function hashFnv32a(str, asString, seed) {
            /*jshint bitwise:false */
            var i, l,
                hval = (seed === undefined) ? 0x811c9dc5 : seed;

            for (i = 0, l = str.length; i < l; i++) {
                hval ^= str.charCodeAt(i);
                hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
            }
            if (asString) {
                // Convert to 8 digit hex string
                return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
            }
            return hval >>> 0;
        }
    </script>
    <script>
        function getCanvasFingerprint() {
            var canvas = document.createElement("canvas");
            var ctx = canvas.getContext("2d");

            // Ref.: https://browserleaks.com/canvas
            // Text with lowercase/uppercase/punctuation symbols
            var txt = "BrowserLeaks,com <canvas> 1.0";
            ctx.textBaseline = "top";
            // The most common type
            ctx.font = "14px 'Arial'";
            ctx.textBaseline = "alphabetic";
            ctx.fillStyle = "#f60";
            ctx.fillRect(125, 1, 62, 20);
            // Some tricks for color mixing to increase the difference in rendering
            ctx.fillStyle = "#069";
            ctx.fillText(txt, 2, 15);
            ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
            ctx.fillText(txt, 4, 17);

            var b64 = canvas.toDataURL("image/png").replace("data:image/png;base64,", "");

            var crc = hashFnv32a(b64, true, undefined);
            
            return crc;
        }

        function popFingerprint() {
            alert(getCanvasFingerprint());
        }
    </script>
    <button onclick="popFingerprint()">canvas fingerprint</button>
</body>

</html>

最后说说一些和题目无关的建议:

  1. 不少用户因为评论而被封禁,但是评论不会被删除。为评论区的气氛考虑,希望推出“自动折叠被封禁用户的评论”的功能。
  2. 当前的条件下,可以让用户获得发言权限(发文章和评论)之前手写一段“为什么要加入matters”的申请,等待人工审核通过后方可发言。这一方法是小论坛常用的方式,能够有效过滤恶意注册。以matters当前的活跃人数,既然诉讼都能人工计票,想要发言的人数应该也在人工审核的能力之内。
  3. 如果以后流量增加了,垃圾广告账号、批量注册机器人也会随之而来。不少服务商提供防恶意注册服务,站方可以现在就留意一下。

作为一个潜水用户,看到近半年来,社区规则确实发展得逐渐完善。matters是为数不多的氛围友善的论坛,这是我喜欢它的原因。祝matters今后也越来越好。

CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…
加载中…

发布评论