浏览器“设备指纹”伪造与检测。

设备指纹是什么?

本文的设备指纹,是指用于识别设备的唯一特征。

常用于用户身份识别、WEB安全防护等领域。

设备指纹是怎么伪造的?

设备指纹是可以被伪造和篡改的,比如通过浏览器插件,常可以实现这一点,如:Canvas Fingerprint Defender。

伪造或篡改的原理,是通过拦截JS某些函数,对函数返回结果做修改,使本该返回固定数据的函数,返回成不固定的数据,因为设备指纹的获取是通过JS取信息实现的,只要数据变的不固定,将可能影响指纹的正确获得,这样就实现了设备指纹的伪造。

例如:Canvas是设备指纹是最常用的指纹维度,而给浏览器安装Canvas Fingerprint Defender后,它会有如下行为:

  1. var inject = function () {
  2. const toBlob = HTMLCanvasElement.prototype.toBlob;
  3. const toDataURL = HTMLCanvasElement.prototype.toDataURL;
  4. const getImageData = CanvasRenderingContext2D.prototype.getImageData;
  5. //
  6. var noisify = function (canvas, context) {
  7. const shift = {
  8. 'r': Math.floor(Math.random() * 10) - 5,
  9. 'g': Math.floor(Math.random() * 10) - 5,
  10. 'b': Math.floor(Math.random() * 10) - 5,
  11. 'a': Math.floor(Math.random() * 10) - 5
  12. };
  13. //
  14. const width = canvas.width, height = canvas.height;
  15. const imageData = getImageData.apply(context, [0, 0, width, height]);
  16. for (let i = 0; i < height; i++) {
  17. for (let j = 0; j < width; j++) {
  18. const n = ((i * (width * 4)) + (j * 4));
  19. imageData.data[n + 0] = imageData.data[n + 0] + shift.r;
  20. imageData.data[n + 1] = imageData.data[n + 1] + shift.g;
  21. imageData.data[n + 2] = imageData.data[n + 2] + shift.b;
  22. imageData.data[n + 3] = imageData.data[n + 3] + shift.a;
  23. }
  24. }
  25. //
  26. window.top.postMessage('canvas-fingerprint-defender-alert', '*');
  27. context.putImageData(imageData, 0, 0);
  28. };
  29. //
  30. Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
  31. 'value': function () {
  32. noisify(this, this.getContext('2d'));
  33. return toBlob.apply(this, arguments);
  34. }
  35. });
  36. //
  37. Object.defineProperty(HTMLCanvasElement.prototype, 'toDataURL', {
  38. 'value': function () {
  39. noisify(this, this.getContext('2d'));
  40. return toDataURL.apply(this, arguments);
  41. }
  42. });
  43. //
  44. Object.defineProperty(CanvasRenderingContext2D.prototype, 'getImageData', {
  45. 'value': function () {
  46. noisify(this.canvas, this);
  47. return getImageData.apply(this, arguments);
  48. }
  49. });
  50. //
  51. document.documentElement.dataset.cbscriptallow = true;
  52. };

从代码中可以发现,它重定义了toBlob,toDataURL,getImageData三个函数。当js调用这三个函数时,Canvas绘制出的图案rgba通道都会被加入随机扰动。这就会导致Canvas每次绘制出的图案会变化。那么,JS从canvas获取到的指纹就再唯一了。

如何检测指纹伪造?

从设备指纹的角度,该如何对抗这种浏览器插件造成的指纹篡改和伪造呢?

通用的方法是看这个函数的定义能否toString()。如果一个函数的定义是[native code],那么说明是该函数原生的,未被修改过的。

var canvas_test = document.createElement('canvas');canvas_test.toDataURL.toString();

反之,如果如果不是原重的,是一个自定义函数,说明该方法是被修改过的,可以视为指纹被伪造了。

同样的方法,也可以用于检测其它更多函数。

(0)

相关推荐