Tuesday, July 21, 2020

Client Fingerprint using fingerprintjs2




This post we will review usage of the fingerprintjs2 library.

This is a javascript library running on the client browser and intended to provide a unique ID for the client. We want the unique ID to identify the client across multiple HTTP sessions. This way we can collect information about the client regardless of a user authentication.

Notice that we cannot use source IP to identify a client due to several reasons:
  • The source IP might change
  • Several clients might use the same source IP, for example in a NAT network topology


The fingerprintjs2 library documentation for the integration seems straightforward:


if (window.requestIdleCallback) {
    requestIdleCallback(function () {
        Fingerprint2.get(function (components) {
          console.log(components) // an array of components: {key: ..., value: ...}
        })
    })
} else {
    setTimeout(function () {
        Fingerprint2.get(function (components) {
          console.log(components) // an array of components: {key: ..., value: ...}
        })  
    }, 500)
}


But, we should ask ourselves, what exactly are we doing: what means are used to create the unique identification of the client. 

We should use the means to allow us to get our purpose: a consistent per client unique ID.
This is importance to understand.
On the one hand, we want to use as many means to create a unique identification, so that we will not have 2 clients getting the same fingerprint.
On the other hand, we want the client identification to be consistent, and not to get updated too frequently.

Checking the fingerprintjs2 library documentation, we can find the list of stable means (components).
So we can select only the stable means, but that's not enough.

For example, do we want to get a different fingerprint on an event of timezone daylight setting change?
Probably not.

Do we want to get a different fingerprint on an event of a client browser update? Note that Chrome and FireFox are updated very often, so we'll probably do want to count on the browser full version.


So, the final configuration we have used is to exclude some of the components:


const options = {
excludes: {
audio: true,
enumerateDevices: true,
doNotTrack: true,
userAgent: true,
timezoneOffset: true,
},
}
fingerPrint.get(options, async (components) => {

This should provide us the target goal: a consistent per client unique ID.




No comments:

Post a Comment