No-JS Fingerprinting is a POC that you can do fingerprinting — a way of uniquely identifying browsers — without the need for JavaScript.
Fingerprinting is a way of identifying browsers without the use of cookies or data storage. Created using properties like language and installed fonts, your fingerprint stays the same even if your browser is in incognito mode.
This demo further illustrates that fingerprinting is possible — even without JavaScript and cookies.
After clicking on “See more details” — or by taking a peek at the HTML source — you can see that the fingerprinting is done using:
@supports
rules (including@supports
rules to detect which browser you are using)- the headers sent in the request
- checking the fonts installed on your system.
When a certain aspect is supported, a request to a server-side script located at /signal/{sessionId}/{feature}/
is made to gather everything:
@supports(-webkit-app-region: inherit) { .css_probe_1 { background: url('/signal/123456789/cssBlink/') } }
@supports(-moz-appearance: inherit) { .css_probe_2 { background: url('/signal/123456789/cssGecko/') } }
@supports(-apple-pay-button-style: inherit) { .css_probe_3 { background: url('/signal/123456789/cssWebkit/') } }
@supports(-webkit-touch-callout: inherit) { .css_probe_4 { background: url('/signal/123456789/cssMobileWebkit/') } }
@supports(-moz-osx-font-smoothing: inherit) { .css_probe_5 { background: url('/signal/123456789/cssMacGecko/') } }
@supports(accent-color: inherit) { .css_probe_6 { background: url('/signal/123456789/cssTorGecko/') } }
…
@font-face { font-family: 'Roboto'; src: local('Roboto'), url('/signal/123456789/robotoFontAbsence/') format('truetype') }
@font-face { font-family: 'Ubuntu'; src: local('Ubuntu'), url('/signal/123456789/ubuntuFontAbsence/') format('truetype') }
@font-face { font-family: 'Calibri'; src: local('Calibri'), url('/signal/123456789/calibriFontAbsence/') format('truetype') }
No-JS Fingerprinting →
No-JS Fingerprinting Source (GitHub) →