Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canvas Fingerprinting on Chrome

I have been experimenting with Canvas Fingerprinting to provide another layer of user identification for my database... It's a layer that I know an experienced hacker can get around since the fingerprint is created client side, but, hey, the more security layers the better, right?

Unfortunately, each Windows 7 computer I test the fingerprint on for Google Chrome produces the same fingerprint. For example, go to this jsfiddle: http://jsfiddle.net/af1pL6fb/5/ All of the Win7/Chrome machines I've used result in a hash of 503251348. If so many different users get the same hash, the fingerprint is useless.

I've tried to draw all sorts of random things on the canvas to get each computer to produce a slightly different result - as is the theory - but with everything I try each Chrome browser keeps giving the same results.

Anyone know of why Chrome is behaving like this when other same browsers of other computers are giving me different results (as expected)?

Or anyone know of something I can include in the canvas to encourage differing results?

OR anyone know of a different metric I can use to diferentiate between computers? For example, I'm looking at the navigator.mimeType array as a potential way of having a semi-unique indicator for a specific browser.

Here's my fingerprint function:

function fingerprint() {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var txt = 'i9asdm..$#po((^@KbXrww!~cz';
    ctx.textBaseline = "top";
    ctx.font = "16px 'Arial'";
    ctx.textBaseline = "alphabetic";
    ctx.rotate(.05);
    ctx.fillStyle = "#f60";
    ctx.fillRect(125,1,62,20);
    ctx.fillStyle = "#069";
    ctx.fillText(txt, 2, 15);
    ctx.fillStyle = "rgba(102, 200, 0, 0.7)";
    ctx.fillText(txt, 4, 17);
    ctx.shadowBlur=10;
    ctx.shadowColor="blue";
    ctx.fillRect(-20,10,234,5);
    var strng=canvas.toDataURL();

    var hash=0;
    if (strng.length==0) return;
    for (i = 0; i < strng.length; i++) {
        char = strng.charCodeAt(i);
        hash = ((hash<<5)-hash)+char;
        hash = hash & hash;
    }
    return hash;
}
like image 781
rgbflawed Avatar asked Aug 26 '14 14:08

rgbflawed


People also ask

How do you do fingerprinting on canvas?

Canvas fingerprinting works by exploiting the HTML5 canvas element: when a user visits a website their browser is instructed to "draw" a hidden line of text or 3D graphic that is then rendered into a single digital token, a potentially unique identifier to track users without any actual identifier persistence on the ...

Does Chrome prevent fingerprinting?

Chrome users can also use extensions to block fingerprints, obscure their IP addresses, and more. Each of these extensions limits tracking (for example, the Canvas Fingerprint Detector blocks the HTML Canvas fingerprint method described above).

How do you test browser fingerprinting?

If you wish to check your browser fingerprint, go to the homepage and click “View my browser fingerprint.” Please note, the website will collect your browser fingerprint and put a cookie on your browser for four months to help with their purpose.


1 Answers

There is a library called fingerprint.js that seems to work pretty well.

  • It will get a fingerprint for non HTML 5 clients
  • Enabling canvas will increase accuracy when available
  • If enabled, it can create a more unique fingerprint based on the plugins installed on the browser (Although not sure why you would need that)

I have embedded this script on my site and you can get fingerprinted here to test. It works in incognito mode on the same browser and Chrome gets fingerprinted differently on other computers.

I am going to try and work on the business logic to try and link fingerprints to the same people. Obviously it is difficult on a dead site like mine where requests are few but its worth a stab.


You could try and use the 32bit CRC on PNG as described on this site. atob not supported in IE <= 9.

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

// crc32 takes only 4 bytes and placed from 16 to 12 byte from the end of file
var crc = bin2hex(bin.slice(-16,-12));

My Signature was FE72FC19 bases on that method.

like image 125
Piotr Kula Avatar answered Sep 16 '22 18:09

Piotr Kula