-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
115 lines (101 loc) · 6.85 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<meta charset="UTF-8">
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<meta name="description" content="">
<title>Device Fingerprinting</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/9.4.4/math.js" integrity="sha512-XTa+nLKjbTCUazCWzwYpykjsTQDaepuKlg9YToCij7+Bdi9aHQhBQlV0rfnYmactJjHdusRQQV+6qWNNv0BScA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.3.1/plotly.min.js" integrity="sha512-Wxp+ZFyiVaCvGlFFlj5NMY6hmzGBnasVpNnkOLX35DsaCRi5hn0PjTIz20mCkGHI+czPfM9E0jTlbq3FtjYSDA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="config.js" type="text/javascript"></script>
<script src="logger.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
</head>
<body>
<noscript>
<style type="text/css">
.container {
display: none;
}
</style>
<div class="noscriptmsg">
JavaScript must be enabled. Please enable JavaScript and reload this page.
</div>
</noscript>
<div id="container" class="container">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 text-justify">
<h1 class="display-4 text-left">Device Fingerprinting with Peripheral Timestamps</h1>
<p class="lead">Authenticate, identify, and track devices based on keyboard, mouse, and touchcreen input in a web browser.</p>
<p>
Almost every personal computer is able to sense and process user input from peripheral sensors, like a touchscreen or keyboard.
<a href="https://github.com/alex/what-happens-when">Dozens of components</a> work together in a pipeline from the time a key is pressed until a character appears on screen.
These components are fairly unique to each device.
This allows fine-grained measurements of DOM event timings in a web browser to reveal timekeeping differences among devices forming the basis for device fingerprinting.
</p>
<p>
The time an event reaches the web page depends on the behavior of several low-frequency components in the pipeline, including:
<ul>
<li>Polling on the peripheral itself (such as <a href="https://en.wikipedia.org/wiki/Keyboard_matrix_circuit">keyboard matrix scanning</a> and touchscreen sampling)</li>
<li>Communication between the peripheral and host (USB, PS/2)</li>
<li>OS process scheduling (when the IRQ get acknowledged, processed, and passed along to the application)</li>
<li>Browser <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop">event loop</a>, which schedules events the timing of callbacks within the web page</li>
</ul>
Low-frequency polling effectively quantizes the event timings in the browser. Because these components may run off of an independent clock from system time, <a href="https://en.wikipedia.org/wiki/Clock_skew">clock skew</a> can be measured
without an explicit reference. Besides clock skew, the <a href="https://en.wikipedia.org/wiki/Instantaneous_phase_and_frequency">instantaneous phase</a> of each low-frequency component reveals idiosynchratic behaviors of the device.
</p>
<p>
This fingerprinting technique works on desktop, laptop, and mobile devices.
No special permissions are required to register callbacks to peripheral DOM events, such as keydown and mousemove, making this technique widely applicable.
For more information, see the <a href='https://vmonaco.com/papers/Device%20Fingerprinting%20with%20Peripheral%20Timestamps.pdf'>paper</a> (in <a href='http://www.ieee-security.org/TC/SP2022'>IEEE S&P 2022</a>).
</p>
</div>
</div>
<hr />
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 text-justify">
<p>
The plots below each show the <a href="https://en.wikipedia.org/wiki/Spectral_density">power spectral density</a> (PSD) updated in real time for common peripheral DOM events: keydown, mousemove, wheel, and touchmove.
Domanint frequencies are peaks in the PSD (labeled in orange), and the fundamental frequency is the lowest frequency that carries a significant amount of energy compared to the rest of the spectrum.
Clock skew is measured as a fine-grained estimate of the fundamental frequency shown in the title of each plot (if the fundamental frequency exists).
For example, the fundamental may be 125Hz (USB device), but actual running frequency could be slightly faster at 125.001Hz.
There are <a href="https://hal.inria.fr/hal-03215569/file/eurosp21_rokicki.pdf">several ways</a> to measure time in a web browser, and both the PSD and fundamental frequency estimates may also differ based on the time source.
</p>
<p>
Try typing in the textarea below (button mashing is OK), moving the mouse around, scrolling, and clicking to see your device's fingerprint.
About 30 events are needed to obtain good estimates, and this improves as more events are generated.
The PSD may differ based on physical device, device type (mobile vs desktop), browser family, OS family, and peripheral (USB vs PS/2 keyboard).
See the code and submit issues <a href="https://github.com/vmonaco/device-fingerprinting">here</a>.
</p>
<p>Change the time source:
<div class="form-check">
<input class="form-check-input" type="radio" name="timeSource" onclick="updateTimeSource();" value="timeStamp" id="eventTimeSource" checked>
<label class="form-check-label" for="native">event.timeStamp</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="timeSource" onclick="updateTimeSource();" value="date" id="dateTimeSource">
<label class="form-check-label" for="dateTimeSource">Date.now()</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="timeSource" onclick="updateTimeSource();" value="performance" id="performanceTimeSource">
<label class="form-check-label" for="performanceTimeSource">performance.now()</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="timeSource" onclick="updateTimeSource();" value="worker" id="workerTimeSource">
<label class="form-check-label" for="workerTimeSource">Web Worker (warning: CPU intensive)</label>
</div>
</p>
<textarea class="form-control" id="scratchpad" rows="3"></textarea>
</div>
</div>
<hr />
</div>
<div id="footer" style="margin-top: 100;">
<div class="container text-center">
<p class="text-muted credit" style="color:#fff">© 2022 <a href='https://vmonaco.com'>Vinnie Monaco</a></p>
</div>
</div>
</body>
</html>