Keystroke JS
Keystroke JS
1 Introduction
Keystroke timing attacks are side-channel attacks where an adversary tries to de-
termine the exact timestamps of user key presses. Keystroke timings convey sen-
sitive information that has been exploited in previous work to recover words and
sentences [39, 49]. More recently, microarchitectural attacks have been demon-
strated to obtain keystroke timings [15, 25, 32, 36] in native code. In particular,
the interrupt-timing side channel leaks highly accurate keystroke timings if an
adversary has access to a cycle-accurate timing source [36].
JavaScript is the most widely used scripting language and supported by vir-
tually any browser today. It is commonly used to create interactive website
elements and enrich the user interface. However, it does not provide access to
native instructions, files, or system services. Still, the ability to execute arbitrary
2 Moritz Lipp et al.
code in the JavaScript sandbox inside a website can also be exploited to perform
attacks on website visitors, e.g., timing attacks [12].
JavaScript-based timing attacks were first presented by Felten et al. [12],
showing that access times to website elements are lower if a website has recently
been visited. Besides attacks on the browser history [12, 21, 46], there have also
been more fine-grained attacks recovering information on the user or other web-
sites visited by the user [8, 16, 22, 40, 41]. Vila and Köpf [43] showed that shared
event loops in Google Chrome leak timing information on other browser tabs
that share worker processes responsible for rendering or I/O.
Previous work has shown that timing side channels which are introduced
on the hardware level or the operating system level, can be exploited from
JavaScript. Gruss et al. [14] demonstrated page deduplication attacks, Oren et al.
[30] demonstrated cache attacks to infer mouse movements and network activity,
and Booth [6] fingerprinted websites based on CPU utilization. Gras et al. [13]
showed that accurate timing information in JavaScript can be exploited to de-
feat address-space layout randomization. Schwarz et al. [37] presented a DRAM
timing covert channel in JavaScript.
In this paper, we present the first generic keystroke timing attack in sand-
boxed JavaScript. Our attack is based on the interrupt-timing side channel which
has previously only been exploited using native code. We show that this side
channel can be exploited from JavaScript without access to native instructions.
Based on instruction throughput variations within equally-sized time windows,
we can detect hardware interrupts, such as keyboard inputs. In contrast to pre-
vious side-channel attacks in JavaScript, our channel provides a more accurate
signal for keystrokes, allowing us to observe exact inter-keystroke timings. We
demonstrate how this information can be used to infer URLs entered by the
user, and distinguish different users time-sharing a computer.
Our attack is generic and can be applied to any system which uses interrupts
for user input. We show that our attack code works both on personal comput-
ers and laptops, as well as modern smartphones. An adversary can target other
browser tabs and browser processes, as well as arbitrary other programs, circum-
venting same-origin policy, HTTPS security model, and both operating system
and browser-level process isolation. With a low impact on the overall system
and browser performance, and a code footprint of less than 256 bytes of code,
the attack can easily be hidden in modern JavaScript frameworks and malicious
online advertisements. Our attack code utilizes new JavaScript features to run
in the background, in a background tab, or on a locked phone. Hence, we can
spy on the PIN entry used to unlock the phone.
To verify our results, we implemented our attack also in Java without ac-
cess to native instructions and only low-accuracy timers. We demonstrate that
the same timing measurements as in JavaScript can be observed in our Java
implementation with a lower noise level. Furthermore, we demonstrate that in
a cross-browser covert channel two websites can communicate through network
interrupts. These observations clearly show that the source of the throughput
differences is caused by the hardware and not specific software implementations.
Practical Keystroke Timing Attacks in Sandboxed JavaScript (updated) 3
2 Background
2.1 Keystroke Timing Attacks
Keystroke timing attacks acquire accurate timestamps of keystrokes for input se-
quences. These keystroke timestamps depend on several factors such as bigrams,
syllables, words, keyboard layout, and typing experience [33]. An adversary can
exploit these timing characteristics to learn information about the user or the
user input. Existing attacks use machine learning to infer typed sentences or
recover passphrases [38, 39, 49]. Idrus et al. [19] showed that key press and key
release events can be used to fingerprint users.
The Linux operating system exposes information that allows compiling ac-
curate traces of keystroke timings [39, 49]. Zhang et al. [49] demonstrated that
instruction and stack pointer, interrupt statistics, and network packet statistics
can be used as side channels for keystroke timings. While Song et al. [39] demon-
strated that SSH leaks inter-keystroke timings in interactive mode, Hogye et al.
[17] showed that network latency in networks with significant traffic conceals
these inter-keystroke timings in practice. Kamran et al. [3] showed that it is
possible to detect keystrokes and classify the typed keys using Wi-Fi Signals.
Jana and Shmatikov [20] showed that CPU usage is a much more reliable side
channel for keystroke timings than the instruction pointer, or the stack pointer.
Diao et al. [11] demonstrated high-precision keystroke timing attacks based on
4 Moritz Lipp et al.
·105
2
Delta [cycles]
p a s s w o r d
0
0.2 0.4 0.6 0.8 1 1.2 1.4
Runtime [cycles] 10
·10
ever the measuring process is interrupted. The more time the operating system
consumes to handle the interrupt, the higher the measured differences are. Es-
pecially interrupts triggered by I/O devices—such as keyboards—lead to clearly
visible peaks in the measured trace. Figure 1 shows a trace from a native attack
implementation while a user typed in a sentence. The exact timestamp where the
user pressed a key is clearly visible and can be distinguished from other events.
However, the trace does not only contain keyboard interrupts and, thus, allows
spying on user input but also on every other event that causes one or more in-
terrupts, e.g., network traffic or redraw events. An adversary can filter relevant
peaks by means of post-processing algorithms to monitor entered keystrokes.
JavaScript has evolved to be the most widely supported scripting language, no-
tably because it is supported by virtually every modern browser. With highly-
optimized just-in-time compilation, modern JavaScript engines deliver a per-
formance that can compete with native code implementations. The timestamp
counter provides a cycle-accurate timestamp to user programs in native code,
but it is not accessible from JavaScript. Instead, JavaScript provides the High
Resolution Time API [45] (performance.now) for sub-millisecond timestamps.
Based on this timing interface, various attacks have been demonstrated. Van
Goethem et al. [41] were able to extract private data from users by measuring the
differences in the execution time from cross-origin resources. Stone [40] showed
that the optimization in SVG filters introduced timing side channels. He showed
that this side channel can be used to extract pixel information from iframes.
Booth [6] fingerprinted websites based on CPU utilization—interfering with the
execution time of a benchmark function—when loading and rendering the page.
Gruss et al. [14] showed that page deduplication timing attacks can be per-
formed in JavaScript to determine which websites the user has currently opened.
Oren et al. [30] showed that it is possible to mount cache attacks in JavaScript.
They demonstrated how to perform Prime+Probe attacks in the browser to
build cache covert channels but also to spy on the user’s mouse movements and
network activity through the cache. This attack caused all major browsers to
decrease the resolution of the performance.now method [1, 7, 10]. The W3C
standard now recommends a resolution of 5 µs while the Tor project reduced
the resolution in the Tor browser to a more conservative value of 100 ms [28].
Gras et al. [13] showed that accurate timing information in JavaScript can be ex-
ploited to defeat address-space layout randomization. Vila and Köpf [43] showed
that shared event loops in Google Chrome leak timing information about other
browser tabs sharing worker processes for rendering and I/O operations. They
exploit this side channel to identify web pages, to build a covert communication
channel, and to infer inter-keystroke timings.
Recently, several works investigated timing primitives in JavaScript that al-
low recovering highly accurate timestamps [13,24,37]. We use these timing prim-
itives to build highly accurate keystroke timing attacks in sandboxed JavaScript.
6 Moritz Lipp et al.
·105
Delta [counter]
1.3
1.28
y a h o o . c o m
1.26
0.1 0.15 0.2 0.25 0.3 0.35
Runtime [s]
Fig. 2: Interrupt-timing attack in JavaScript: The lower peaks indicate that the
measured script has been interrupted, allowing to infer single keystrokes.
result of Vila and Köpf [43] who achieved a resolution of only 25 µs to 100 µs.
On ARM, we achieve on average 5038 increments on the Google Nexus 5 and
17 454 increments on the OnePlus 3T, yielding a resolution of 994 ns (σ = 55 ns,
n = 4000) and 287 ns (σ = 4 ns, n = 4000) respectively.
A further limitation of JavaScript is that once the user switches the tab or
minimizes the browser, the default minimum timeout value of 4 ms is reduced to
1000 ms. Increasing the loop slices to 1000 ms is not practical since it would make
the browser unresponsive again. In order to circumvent this issue, we utilize the
Web Worker API which explicitly allows JavaScript code to be executed in the
background [44]. We discovered that the minimum timeout is not reduced for
web workers and we can still measure interrupt timings with a high frequency.
This allows us to monitor keystrokes when the victim is visiting a different page
or even a different application.
Figure 2 shows a measured trace while a user typed the URL yahoo.com into
the browser bar. If no interrupt occurs, the counter variable has been incremented
for the full time window of 4 ms, defining the baseline. If an interrupt disrupts
the measuring JavaScript, the counter variable is not incremented as often in the
same time window, yielding to downward-facing peaks. Thus, the typed letters
leave clear marks in the measured trace, which allows inferring single keystrokes.
Offline phase. In the offline phase of the attack, the measurements gathered from
the online phase are processed and analyzed. Over time, an adversary can gather
thousands of traces in order to learn about the individual typing behavior of the
victim or to derive an entered passphrase or PIN code. Depending on the goal of
8 Moritz Lipp et al.
the adversary, different methods to evaluate the gathered data can be applied.
In order to detect single keystrokes in a measured trace, we filter the measured
trace in order to reduce noise and to deduce threshold values for keystrokes by
manually inspecting one recorded trace of the target device. Using this threshold,
we can further reduce the number of points in recorded traces to a minimum and,
thus, increase the performance of further computations. We build a classifier by
calculating the correlation between our training set and the queried trace. In
order to classify entered words, we need to take into account that the points in
time where a character has been entered can vary in time in our trace. Therefore,
we use k-nearest neighbors (k-NN) classification [4] and calculate the correlation
of the trace with every other trace in the training set using different alignments.
We chose the alignment that yields the highest correlation and decide on the class
giving the best match. While more computational expensive methods working
with time series [5, 35] to build classifiers exist [9, 23, 48], we show that the
features of the recorded measurements are strong enough such that also simpler
techniques allow to build an efficient and accurate classifier.
amazon.com 0.81 0.04 0.01 0.04 0.02 0.03 0.03 0.02 0.00 0.00
baidu.com 0.00 0.84 0.03 0.05 0.02 0.00 0.03 0.01 0.00 0.02
facebook.com 0.04 0.02 0.72 0.02 0.00 0.05 0.01 0.10 0.04 0.00
google.co.in 0.03 0.04 0.02 0.67 0.06 0.03 0.02 0.07 0.02 0.04
Actual URL
google.co.jp 0.00 0.01 0.00 0.09 0.73 0.08 0.00 0.06 0.02 0.01
google.com 0.00 0.00 0.03 0.00 0.01 0.86 0.06 0.00 0.02 0.02
qq.com 0.00 0.00 0.00 0.00 0.00 0.02 0.96 0.00 0.01 0.01
wikipedia.org 0.02 0.04 0.10 0.06 0.05 0.02 0.02 0.69 0.00 0.00
yahoo.com 0.00 0.01 0.00 0.00 0.00 0.03 0.01 0.00 0.92 0.03
youtube.com 0.00 0.03 0.00 0.00 0.02 0.08 0.05 0.00 0.09 0.73
ip com
ba .com
og .in
og jp
om
ho rg
ub m
m
bo com
og om
ut co
co
go .co.
ya a.o
go e.co
.c
go .c
yo o.
e.
.
q
on
le
fa idu
ok
i
le
ed
q
l
az
am
ce
ik
w
Predicted URL
Fig. 3: Confusion matrix for URL input. The user input can be correctly pre-
dicted with a probability of 67 % in the worst case and 96 % in the best case.
The probability of random guessing is 10 %.
Actual User
P2 0.27 0.47 0.17 0.10
P1
P2
P3
P4
Predicted User
Fig. 4: Confusion matrix for input by different users. The user can be correctly
predicted with a probability of 43 % in the worst case and 53 % in the best case.
The probability of random guessing is 25 %.
rate of qq.com in comparison with other domains is also very high as the domain
contains only a small number of characters to be typed. The overall identification
rate of our classifier is 81.75 %.
Delta [counter]
4,000
3,000
0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7
Runtime [s]
Fig. 5: Keystroke timing attack running in a native app on the Google Nexus 5.
Delta [counter]
3,000
2,000
1,000
tap tap swipe tap
0
0.4 0.6 0.8 1 1.2 1.4
Runtime [s]
8,500
8,000
7,500
7,000 tap tap swipe tap
6,500
0.1 0.2 0.3 0.4 0.5 0.6 0.7
Runtime [s]
Fig. 7: Keystroke timing attack running in Chrome on the Xiaomi Redmi Note
3. The peaks face upwards instead of downwards as with other devices.
JavaScript contain much more noise, the exact tap timings can easily be ex-
tracted and allow further, more sophisticated attacks.
Figure 7 shows the same trace of two taps, one swipe and one additional
tap on the Xiaomi Redmi Note 3. Surprisingly, the peaks caused by the inter-
rupts face upwards instead of downwards as one might expect. We observed that
the Xiaomi Redmi Note 3 increases the CPU frequency whenever the screen is
touched. Consequently, although the interrupt will consume some CPU time,
the counter as described in Section 3 can be incremented more often due to the
significantly higher CPU frequency. We have verified this behavior by running a
benchmark suite on the Xiaomi Redmi Note 3. The benchmark suite has been up
to 30 % faster, when swiping over the screen while the benchmark is executed.
While this feature may be useful to handle touch interrupts more efficiently and
to appear more responsive, it also opens a new side channel and allows detecting
tap and screen events easily. We also verify the same behavior in our native Java
implementation with higher peaks which allows detecting tap and swipe events
even more reliably. On the OnePlus 3T we were not able to detect keystrokes
at all. We suspect that this is due to the big.LITTLE architecture, which moves
the CPU-intensive browser task to a high-performance ARM core, while the in-
terrupts are handled by smaller cores. Thus, the browser is not interrupted if a
hardware interrupt occurs.
Spying on other applications and PIN unlock. While the attack of Vila and
Köpf [43] is limited to spy on tabs or pop-ups opened by the adversary, our at-
tack is not restricted and can be used to monitor any other application running
Practical Keystroke Timing Attacks in Sandboxed JavaScript (updated) 13
Delta [counter]
10,000 tap menu new tab tap swipe tap switch tab select tab activate tab
5,000
redraw
incognito tab
redraw redraw redraw redraw
0
0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
Runtime [s]
Fig. 8: Keystroke timing attack running while switching to a different tab in the
Chrome browser on the Xiaomi Redmi Note 3.
on the system. Indeed, the attack of Vila and Köpf relies on the timing differ-
ence caused by the event loop of the render process, thus only tabs or windows
sharing the same rendering process can be attacked. In contrast, our interrupt-
timing attack is not restricted to the browser and its child processes as it allows
monitoring every other event triggering interrupts on the target device. More-
over, our attack also provides a much higher resolution, which allows detecting
interrupts triggered by user input more reliably.
Figure 8 shows a trace of a victim opening a website running the measurement
code in Chrome on the Xiaomi Redmi Note 3. In addition, the victim opens a tab
in incognito mode and taps the screen multiple times. We can even detect these
user interactions in different tabs as the attack takes advantage of web workers
which are not throttled when running in the background. Thus, the incognito
mode offers no protection against our attack.
In the next scenario, we show that our attack is not restricted to processes of
the browser application but can be used to spy on every other application as well.
The victim visits the website running the measuring application in the Firefox
app on the Xiaomi Redmi Note 3 and continues using the phone, switching to
other tabs or applications, and later locks the screen. After some time the victim
turns on the screen again, where the lock screen prompts the victim for the PIN
code. Finally, the victim enters the PIN code, unlocking the phone. Figure 9
shows a trace of this scenario. We can clearly observe when the screen is turned
off as the CPU frequency is lowered to save battery, as well as when the screen
is turned on again. Furthermore, we can extract the exact timestamps where the
victim entered the 4-digit PIN and the subsequent redraw event.
Delta [counter]
10,000 slide 1 2 3 4 tap
screen off
5,000
0 redraw redraw
Fig. 9: Keystroke timing attack running in the Firefox browser on the Xiaomi
Redmi Note 3. While the user locked the screen, the application still detects
keystrokes as long as it is executed on the last used tab. The application extracts
the exact inter-keystroke timings for the PIN input used to unlock the device.
Cross-tab channel. Using the covert channel across tabs breaks two security
mechanisms. First, the same origin policy—which prevents any communication
between scripts from different domains—does not apply anymore. Thus, scripts
can communication across domain borders. Second, due to the security model
of browsers, there is no way a HTTPS page is able to load HTTP content. For
the covert channel, this security model does not hold anymore.
5 Countermeasures
5.1 A Fine-grained Permission Model for JavaScript
In order to impede and mitigate our interrupt-timing attack and other similar
side-channel attacks in JavaScript, we propose a more fine-grained permission
Practical Keystroke Timing Attacks in Sandboxed JavaScript (updated) 15
model for JavaScript running in web browsers. For instance, the existing per-
mission system of Firefox only allows managing the access control to a limited
number of APIs. However, as many websites do not require functionality such
as web workers. The user should be capable to allow on a per-page level such
features. If an online advertisement running potential malicious code requests
for permissions to uncommon APIs, the fine-grained permission system prevents
its further execution.
6 Conclusion
Delta [counter]
5,000
4,000
3,000
Fig. 10: Measurement of the keystroke timing attack running in the Chrome
Browser on the Google Nexus 5. The red rectangles show when the user tapped
the screen. In the gray area, we enabled the countermeasure [36], making it
infeasible to distinguish real keystrokes from fake keystrokes.
well as taps and swipes on mobile devices. Based on these keystroke traces,
we built classifiers to detect which websites a user has visited and to identify
different users time-sharing a computer. Our attack is highly practical, as it
works while the browser is running in the background, allowing to spy on other
tabs and applications. As the attack is also executed when the phone is locked,
we demonstrated that we can monitor the PIN entry that is used to unlock the
phone. Finally, as a solution against our attack and other similar side-channel
attacks in JavaScript, we proposed a fine-grained permission model for browsers.
Acknowledgments
We would like to thank our anonymous reviewers for their valuable feedback.
This project has been supported by the COMET K-Project DeSSnet (grant No
862235) conducted by the Austrian Research Promotion Agency (FFG) and the
European Research Council (ERC) under the European Union’s Horizon 2020
research and innovation programme (grant agreement No 681402).
References
28. Mike Perry: Bug 1517: Reduce precision of time for Javascript. (2015),
https://gitweb.torproject.org/user/mikeperry/tor-browser.git/commit/
?h=bug1517
29. Myers, M.: Anti-Keylogging with Random Noise. In: PoC|GTFO. vol. 0x14 (2017)
30. Oren, Y., Kemerlis, V.P., Sethumadhavan, S., Keromytis, A.D.: The Spy in the
Sandbox: Practical Cache Attacks in JavaScript and their Implications. In: CCS’15
(2015)
31. Ortolani, S.: Noisykey: Tolerating keyloggers via keystrokes hiding. In: USENIX
Workshop on Hot Topics in Security – HotSec (2012)
32. Pessl, P., Gruss, D., Maurice, C., Schwarz, M., Mangard, S.: DRAMA: Exploit-
ing DRAM Addressing for Cross-CPU Attacks. In: USENIX Security Symposium
(2016)
33. Pinet, S., Ziegler, J.C., Alario, F.X.: Typing is writing: Linguistic properties mod-
ulate typing execution. Psychon Bull Rev 23(6), 1898–1906 (Apr 2016)
34. Ristenpart, T., Tromer, E., Shacham, H., Savage, S.: Hey, You, Get Off of My
Cloud: Exploring Information Leakage in Third-Party Compute Clouds. In: CCS’09
(2009)
35. Rumelhart, D.E., McClelland, J.L., PDP Research Group, C. (eds.): Parallel Dis-
tributed Processing: Explorations in the Microstructure of Cognition, Vol. 1: Foun-
dations. MIT Press (1986)
36. Schwarz, M., Lipp, M., Gruss, D., Weiser, S., Maurice, C., Spreitzer, R., Man-
gard, S.: KeyDrown: Eliminating Software-Based Keystroke Timing Side-Channel
Attacks. In: NDSS’18 (2018), (to appear)
37. Schwarz, M., Maurice, C., Gruss, D., Mangard, S.: Fantastic Timers and Where to
Find Them: High-Resolution Microarchitectural Attacks in JavaScript. In: FC’17
(2017)
38. Simon, L., Xu, W., Anderson, R.: Don’t Interrupt Me While I Type: Inferring Text
Entered Through Gesture Typing on Android Keyboards. Proceedings on Privacy
Enhancing Technologies (2016)
39. Song, D.X., Wagner, D., Tian, X.: Timing Analysis of Keystrokes and Timing
Attacks on SSH. In: USENIX Security Symposium (2001)
40. Stone, P.: Pixel perfect timing attacks with html5. Context Information Security
(White Paper) (2013)
41. Van Goethem, T., Joosen, W., Nikiforakis, N.: The clock is still ticking: Timing
attacks in the modern web. In: CCS’15 (2015)
42. Vattikonda, B.C., Das, S., Shacham, H.: Eliminating fine grained timers in Xen.
In: CCSW’11 (2011)
43. Vila, P., Köpf, B.: Loophole: Timing attacks on shared event loops in chrome. In:
USENIX Security Symposium (2017)
44. W3C: Web Workers - W3C Working Draft 24 September 2015 (2015), https:
//www.w3.org/TR/workers/
45. W3C: High Resolution Time Level 2 (2016), https://www.w3.org/TR/hr-time/
46. Weinberg, Z., Chen, E.Y., Jayaraman, P.R., Jackson, C.: I still know what you
visited last summer: Leaking browsing history via user interaction and side channel
attacks. In: S&P’11 (2011)
47. Wray, J.C.: An analysis of covert timing channels. Journal of Computer Security
1(3-4), 219–232 (1992)
48. Xi, X., Keogh, E., Shelton, C., Wei, L., Ann Ratanamahatana, C.: Fast Time Series
Classification Using Numerosity Reduction. In: Proceedings of the 23rd Interna-
tional Conference on Machine Learning (2006)
Practical Keystroke Timing Attacks in Sandboxed JavaScript (updated) 19
49. Zhang, K., Wang, X.: Peeping Tom in the Neighborhood: Keystroke Eavesdropping
on Multi-User Systems. In: USENIX Security Symposium (2009)