瀏覽器“裝置指紋”偽造與檢測

裝置指紋是什麼?

本文的裝置指紋,是指用於識別裝置的唯一特徵。

常用於使用者身份識別、WEB安全防護等領域。

瀏覽器“裝置指紋”偽造與檢測

裝置指紋是怎麼偽造的?

裝置指紋是可以被偽造和篡改的,比如透過瀏覽器外掛,常可以實現這一點,如:Canvas Fingerprint Defender。

偽造或篡改的原理,是透過攔截JS某些函式,對函式返回結果做修改,使本該返回固定資料的函式,返回成不固定的資料,因為裝置指紋的獲取是透過JS取資訊實現的,只要資料變得不固定,將可能影響指紋的正確獲得,這樣就實現了裝置指紋的偽造。

例如:Canvas是裝置指紋是最常用的指紋維度,而給瀏覽器安裝Canvas Fingerprint Defender後,它會有如下行為:

var inject = function () {

const toBlob = HTMLCanvasElement。prototype。toBlob;

const toDataURL = HTMLCanvasElement。prototype。toDataURL;

const getImageData = CanvasRenderingContext2D。prototype。getImageData;

//

var noisify = function (canvas, context) {

const shift = {

‘r’: Math。floor(Math。random() * 10) - 5,

‘g’: Math。floor(Math。random() * 10) - 5,

‘b’: Math。floor(Math。random() * 10) - 5,

‘a’: Math。floor(Math。random() * 10) - 5

};

//

const width = canvas。width, height = canvas。height;

const imageData = getImageData。apply(context, [0, 0, width, height]);

for (let i = 0; i < height; i++) {

for (let j = 0; j < width; j++) {

const n = ((i * (width * 4)) + (j * 4));

imageData。data[n + 0] = imageData。data[n + 0] + shift。r;

imageData。data[n + 1] = imageData。data[n + 1] + shift。g;

imageData。data[n + 2] = imageData。data[n + 2] + shift。b;

imageData。data[n + 3] = imageData。data[n + 3] + shift。a;

}

}

//

window。top。postMessage(“canvas-fingerprint-defender-alert”, ‘*’);

context。putImageData(imageData, 0, 0);

};

//

Object。defineProperty(HTMLCanvasElement。prototype, “toBlob”, {

“value”: function () {

noisify(this, this。getContext(“2d”));

return toBlob。apply(this, arguments);

}

});

//

Object。defineProperty(HTMLCanvasElement。prototype, “toDataURL”, {

“value”: function () {

noisify(this, this。getContext(“2d”));

return toDataURL。apply(this, arguments);

}

});

//

Object。defineProperty(CanvasRenderingContext2D。prototype, “getImageData”, {

“value”: function () {

noisify(this。canvas, this);

return getImageData。apply(this, arguments);

}

});

//

document。documentElement。dataset。cbscriptallow = true;

};

從程式碼中可以發現,它重定義了toBlob,toDataURL,getImageData三個函式。當js呼叫這三個函式時,Canvas繪製出的圖案rgba通道都會被加入隨機擾動。這就會導致Canvas每次繪製出的圖案會變化。那麼,JS從canvas獲取到的指紋就再唯一了。

如何檢測指紋偽造?

從裝置指紋的角度,該如何對抗這種瀏覽器外掛造成的指紋篡改和偽造呢?

通用的方法是看這個函式的定義能否toString()。如果一個函式的定義是[native code],那麼說明是該函式原生的,未被修改過的。

var canvas_test = document。createElement(‘canvas’);canvas_test。toDataURL。toString();

瀏覽器“裝置指紋”偽造與檢測

反之,如果如果不是原重的,是一個自定義函式,說明該方法是被修改過的,可以視為指紋被偽造了。

同樣的方法,也可以用於檢測其它更多函式。