Introduction
Most popular tracking methods involve persistent identifiers, like the famous cookies. But what if we delete those cookies? What if we go incognito?
It turns out that there other ways to track users without relying on persistent identifiers. Browser fingerprinting is one of them. Since it doesn't need to store anything, there's nothing to delete and going private won't do the trick.
We'll write a small React app to demonstrate how to collect a device's fingerprint and IP address metadata. The app will run entirely in the browser, and no data will be stored.
Motivation
By gathering that information together and storing it on its own servers, a site can track your browsing habits without the use of persistent identifiers stored on your computer, like cookies. Fingerprinting can also be used to recreate a tracking cookie for a user after the user has deleted it. Users that are aware of cookies can remove them within their browser settings, but fingerprinting subverts the built-in browser mechanisms that allow users to avoid being tracked. (EFF | The GDPR and Browser Fingerprinting: How It Changes the Game for the Sneakiest Web Trackers).
What we're building
To build the app, we'll use:
- Fingerprintjs2 to collect the fingerprint. This will gives us the device's platform, RAM, number of cores and other juicy info.
- The Extreme IP Lookup API to get the IP address metadata. This provides info such as the device's location, ISP, etc...
- React Hooks to manage the application's state while minimizing boilerplate. Since we're going for a light-weight approach, we'll favor this option over something like Redux.
How it works
Getting the device's fingerprint
Fingerprintjs2
automatically detects the running browser's features, then selectively query the parameters that are available. Some of the identification methods it uses include:
- Canvas fingerprinting. By drawing text and adding background colors, a script then calls the Canvas API to get a Base64 encoded representation of the binary pixel data. That representation is then turned into a hash, which will serve as a fingerprint.
- Font detection. Based on what fonts you have, and how they are drawn. By measuring the dimensions of the filled, we can model a fingerprint.
- Browser plugin probing.
- Audio sampling.
- WebGL fingerprinting.
To actually get the fingerprint we'll use the get
function of Fingerprintjs2
, and it looks like this:
import fp from "fingerprintjs2";
// We re-write the callback into a Promise style,
// so it plays nice with React Hooks
export const getFingerprint = () =>
new Promise(resolve => {
fp.get(components => {
resolve(components);
});
});
Getting the IP address metadata
IP-based Geolocation is a mapping of an IP address or MAC address to the real-world geographic location of an Internet-connected computing or a mobile device. Geolocation involves mapping an IP address to the country, region (city), latitude/longitude, ISP and domain name among other useful things. More about here.
No magic involved here. Geo-location works by simply using a pre-populated database with relevant information. There are also many free (and paid) services that do this for you, like the one we're using in this tutorial.
We'll use a standard HTTP GET request to the extreme-ip-lookup
REST API. We'll also specify that we want json
as the returning response format.
// Standard HTTP GET using "fetch"
fetch("https://extreme-ip-lookup.com/json")
.then(res => res.json())
Creating the component
Now let's bring everything together and create our main component. Since our data fetching is asynchronous, we'll use the useEffect
hook to populate our component.
import React, { useEffect, useState } from "react";
import { getFingerprint } from "./utils"; // The method we wrote above
import DataTable from "./dataTable"; // Custom component to render our data
function App() {
const [fingerprint, setFingerprint] = useState(null);
const [ipData, setIpData] = useState(null);
const [showReport, setShowReport] = useState(true);
useEffect(() => {
if (showReport) {
fetch("https://extreme-ip-lookup.com/json") // Get the IP data
.then(res => res.json())
.then(ip => Promise.all([ip, getFingerprint()])) // Get the fingerprint
.then(([ip, fp]) => {
setFingerprint(fp); // Update the state
setIpData(ip);
setShowReport(false);
});
}
}, [showReport]);
return (
<div>
{ipData && fingerprint ? (
<div>
<DataTable title="IP Data" data={ipData} />
<DataTable title="Fingerprint" data={fingerprint} />
</div>
) : (
<div>
<h2>Please wait...</h2>
</div>
)}
</div>
);
}
export default App;
Notes
The app will not store any collected info, but we can easily change it and give it storage capabilities. We could:
- Use the
localStorage
API to store the results in the browser. - Send the collected data to a server that we built that will store it in a database for future use.
Github repository
molamk / fingerprint
Sneaky fingerprint and IP address tracker
Sneaky fingerprint and IP tracker with React
Introduction
The most popular tracking methods involve persistent identifiers, like famous cookies. But what if we delete those cookies? What if we go incognito?
It turns out that there other ways to track users without relying on persistent identifiers. Browser fingerprinting is one of them. Since it doesn't need to store anything, there's nothing to delete and going private won't do the trick.
We'll write a small React app to demonstrate how to collect a device's fingerprint and IP address metadata. The app will run entirely in the browser, and no data will be stored.
Motivation
By gathering that information together and storing it on its own servers, a site can track your browsing habits without the use of persistent identifiers stored on your computer, like cookies. Fingerprinting can also be used to recreate a tracking cookie for a…
Running it
git clone git@github.com:molamk/fingerprint.git
cd fingerprint
yarn install
yarn start
Top comments (1)
No doubt, with IP, you can get so much about the user
Form IP, what you can get, you can see here
browserleaks.com/ip
dnschecker.org/whats-my-ip-address...
iplocation.io/what-is-my-ip-address