Fantastic Timers and Where to Find Them:
High-Resolution Microarchitectural
Attacks in JavaScript
Michael Schwarz, Clémentine Maurice, Daniel Gruss, and Stefan Mangard
Graz University of Technology, Austria

Abstract. Research showed that microarchitectural attacks like cacheattacks can be performed through websites using JavaScript. These timing attacks allow an adversary to spy on users secrets such as their
keystrokes, leveraging fine-grained timers. However, the W C and browser
vendors responded to this significant threat by eliminating fine-grained
timers from JavaScript. This renders previous high-resolution microarchitectural attacks non-applicable.
We demonstrate the inefficacy of this mitigation by finding and evaluating a wide range of new sources of timing information. We develop measurement methods that exceed the resolution of official timing sources
by to orders of magnitude on all major browsers, and even moreon Tor browser. Our timing measurements do not only re-enable previous attacks to their full extent but also allow implementing new attacks.
We demonstrate a new DRAM-based covert channel between a website
and an unprivileged app in a virtual machine without network hardware. Our results emphasize that quick-fix mitigations can establish adangerous false sense of security.

Introduction
Microarchitectural attacks comprise side-channel attacks and covert channels,
entirely implemented in software. Side-channel attacks exploit timing differences
to derive secret values used in computations. They have been studied extensively
in the past
years with a focus on cryptographic algorithms [ , , , – , ].
Covert channels are special side channels where a sender and a receiver use theside channel actively to transmit data covertly. These attacks require highly
accurate timing and thus are typically implemented in native binaries written
in C or assembly language to use the best available timing source.
Side channels exist on virtually all systems and software not hardened againstside channels. Thus, browsers are an especially easy target for an attacker, because browsers process highly sensitive data and attackers can easily trick a
victim to open a malicious website in the browser. Consequently, timing sidechannel attacks have been demonstrated and observed in the wild, to recovera user’s browser history [ , , ], but also a user’s geolocation [ ], whether
a user is logged in to another website [ ] and even CSRF tokens [ ]. Van

M. Schwarz, C. Maurice, D. Gruss, S. Mangard

Goethem et al. [ ] exploited more accurate in-browser timing to obtain information even from within other websites, such as contact lists or previous
inputs.
Oren et al. [ ] recently demonstrated that cache side-channel attacks canalso be performed in browsers. Their attack uses the performance.now method
to obtain a timestamp whose resolution is in the range of nanoseconds. It allows
spying on user activities but also building a covert channel with a process runningon the system. Gruss et al. [ ] and Bosman et al. [ ] demonstrated Rowhammer attacks in JavaScript, leveraging the same timing interface. In response,
the W C [ ] and browser vendors [ , , ] have changed the performance.now
method to a resolution of 5 µs. The timestamps in the Tor browser are even morecoarse-grained, at 100 ms [ ]. In both cases, this successfully stops side-channel
attacks by withholding necessary information from an adversary.
In this paper, we demonstrate that reducing the resolution of timing information or even removing these interfaces is completely insufficient as an attack
mitigation. We propose several new mechanisms to obtain absolute and relative
timestamps. We evaluateddifferent mechanisms on the most recent versionsof different browsers: Chrome, Firefox, Edge, as well as the Tor browser, which
took even more drastic measures. We show that all browsers leak highly accurate
timing information that exceeds the resolution of official timing sources by toorders of magnitude on all browsers, and by on the Tor browser. In all cases,
the resolution is sufficient to revive the attacks that were thought mitigated [ ].
Based on our novel timing mechanisms, we are the first to exploit DRAMbased timing leaks from JavaScript. There were doubts whether DRAM-basedtiming leaks can be exploited from JavaScript, as it is not possible to directly
reach DRAM [ ]. We demonstrate that a DRAM-based covert channel can beused to exfiltrate data from highly restricted, isolated execution environmentsthat are not connected to the network. More specifically, we transmit data froman unprivileged process in a Virtual Machine (VM) without any network hardware to a website, by tunneling the data through the DRAM-based covert channel to the JavaScript running in a web browser on the same host machine.
Our key contributions are:
– We performed a comprehensive evaluation of known and new mechanisms to
obtain timestamps. We comparedmethods on the major browsers on
Windows, Linux and Mac OS X, as well as on Tor browser.
– Our new timing methods increase the resolution of official methods by
to orders of magnitude on all browsers, and by orders of magnitude on
Tor browser. Our evaluation therefore shows that reducing the resolution oftimer interfaces does not mitigate any attack.
– We demonstrate the first DRAM-based side channel in JavaScript to exfiltrate data from a highly restricted execution environment inside a VM withno network interfaces.
– Our results underline that quick-fix mitigations are dangerous, as they canestablish a false sense of security.

Fantastic Timers and Where to Find Them

The remainder of this paper is organized as follows. In Section , we provide
background information. In Section , we comprehensively evaluate new timing
measurement methods on all major browsers. In Section , we demonstrate therevival of cache attacks with our new timing primitives as well as a new DRAMbased covert channel between JavaScript in a website and a process that isstrictly isolated inside a VM with no network hardware. Finally, we discuss
effective mitigation techniques in Section and conclude in Section .

Background.

Microarchitectural attacks

A large body of recent work has focused on cross-VM covert channels. A first classof work uses the CPU cache for covert communications. Ristenpart et al. [ ]are the first to demonstrate a cache-based covert channel between two Amazon
EC instances, yielding 0.2 bps. Xu et al. [ ] optimized this covert channel
and assessed the difference in performance between theoretical and practicalresults. They obtain 215.11 bps with an error rate of . %. Maurice et al. [ ]built a cross-VM covert channel, using the last-level cache and a Prime+Probeapproach, that achieves a bit rate of 751 bps with an error rate of . %. Liu et al.
[ ] demonstrated a high-speed cache-based covert channel between two VMs
that achieves transmission speeds of up to 600 Kbps and an error rate of less than%. In addition to the cache, covert channels have also been demonstrated using
memory. Xiao et al. [ ] demonstrated a memory-based covert channel using
page deduplication. Wu et al. [ ] built a covert channel of 746 bps with error
correction, using the memory bus. Pessl et al. [ ] reverse engineered the DRAM
addressing functions that map physical addresses to their physical location inside
the DRAM. The mapping allowed them to build a covert channel that relies solely
on the DRAM as shared resource. Their cross-core cross-VM covert channel
achieves a bandwidth of 309 Kbps. Maurice et al. [ ] demonstrated an errorfree covert channel between two Amazon EC instances of more than 360 Kbps,
which allows building an SSH connection through the cache.
.

JavaScript and timing measurements

JavaScript is a scripting language supported by all modern browsers, which
implement just-in-time compilation for performance. Contrary to low-level languages like C, JavaScript is strictly sandboxed and hides the notion of addresses
and pointers. The concurrency model of JavaScript is based on a single-threaded
event loop [ ], which consists of a message queue and a call stack. Events arehandled in the message queue, moved to the call stack when the stack is empty
and processed to completion. As a drawback, if a message takes too long toprocess, it blocks other messages to be processed, and the browser becomes
unresponsive. Browsers received the support for multithreading with the introduction of web workers. Each web worker runs in parallel and has its own event
loop [ ].

M. Schwarz, C. Maurice, D. Gruss, S. Mangard

For timing measurement, the timestamp counter of Intel CPUs provides thenumber of CPU cycles since startup and thus a high-resolution timestamp. In
native code, the timestamp counter is accessible through the unprivileged rdtsc
instruction. In JavaScript, we cannot execute arbitrary instructions such as therdtsc instruction. One of the timing primitives provided by JavaScript is the High
Resolution Time API [ ]. This API provides the performance.now methodthat gives a sub-millisecond timestamp. The W C standard recommends thatthe timestamp should be monotonically increasing and accurate to 5 µs. The
resolution may be lower if the hardware has no support for such a high resolution.
Remarkably, until Firefox
the High Resolution Time API returned timestamps accurate to one nanosecond. This is comparable to the native rdtsc instruction which has a resolution of 0.5 ns on a 2 GHz CPU. As a response to
the results of Oren et al. [ ], the timer resolution was decreased for security
reasons [ ]. In recent versions of Chrome and WebKit, the timing resolution was
also decreased to the suggested 5 µs [ , ]. The Tor project even reduced theresolution to 100 ms [ ]. The decreased resolution of the high-resolution timer
is supposed to prevent time-based side-channel attacks. In a concurrent work,
Kohlbrenner et al. [ ] showed that it is possible to recover a high resolution
by observing clock edges, as well as to create new implicit clocks using browser
features. Additionally, they implemented fuzzy time that aims to degrade thenative clock as well as all implicit clocks.
.

Timing attacks in JavaScript

Van Goethem et al. [ ] showed different timing attacks in browsers based on
the processing time of resources. They aimed to extract private data from users
by estimating the size of cross-origin resources. Stone [ ] showed that the optimization in SVG filters introduced timing side channels. He showed that thisside channel can be used to extract pixel information from iframes.
Microarchitectural side channels have only recently been exploited in JavaScript. Oren et al. [ ] showed that it is possible to mount cache attacks in
JavaScript. They demonstrated how to generate an eviction set for the last-level
cache that can be used to mount a Prime+Probe attack. Based on this attack,they built a covert channel using the last-level cache that is able to transmit
data between two browser instances. Furthermore, they showed that the timer
resolution is high enough to create a spy application that tracks the user’s mouse
movements and network activity. As described in Section . , this attack caused
all major browsers to decrease the resolution of the performance.now method.
Gruss et al. [ ] demonstrated hardware faults triggered from JavaScript,
exploiting the so-called Rowhammer bug. The Rowhammer bug occurs when
repeatedly accessing the same DRAM cells with a high frequency [ ]. This
“hammering” leads to bit flips in neighboring DRAM rows. As memory accesses
are usually cached, they also implemented cache eviction in JavaScript.
All these attacks require a different timestamp resolution. The attacks from
Goethem et al. [ ] and Stone [ ] require a timestamp resolution that is on
the order of a microsecond, while the attack of Oren et al. [ ] relies on theFantastic Timers and Where to Find Themfine-grained timestamps on the order of nanoseconds. More generally, as microarchitectural side channel attacks aim at exploiting timing differences of a
few CPU cycles, they depend on the availability of fine-grained timestamps. We
note that decreasing the resolution therefore only mitigates microarchitecturalattacks on the major browsers that have a resolution of 5 µs, but mitigates moreside-channel attacks on the Tor browser which has a resolution of 100 ms.

Timing Measurements in the JavaScript Sandbox
This section describes techniques to get accurate measurements with a highresolution timestamp in the browser. In the first part, we describe methods
to recover a high resolution for the provided High Resolution Time API. The
second part describes different techniques that allow deriving highly accurate
timestamps, with implicit timers. These methods are summarized in Table .
.

Recovering a high resolution

In both Chrome and Webkit, the timer resolution is decreased by rounding thetimestamp down to the nearest multiple of 5 µs. As our measurements fall below
this resolution, they are all rounded down to . We refer to the underlying clock’s
resolution as internal resolution and to the decreased resolution of the provided
timer as provided resolution. It has already been observed that it is possible
to recover a high resolution by observing the clock edges [ , , , ]. The
clock edge aligns the timestamp perfectly to its resolution, i.e., we know thatthe timestamp is an exact multiple of its provided resolution at this time.
Clock interpolation As the underlying clock source has a high resolution, thedifference between two clock edges varies only as much as the underlying clock.
This property gives us a very accurate time base to build upon. As the time
between two edges is always constant, we interpolate the time between them.
This method has also been used in JavaScript in a concurrent work [ ].
Clock interpolation requires a calibration before being able to return accurate
timestamps. For this purpose, we repeatedly use a busy-wait loop to increment a
counter between two clock edges. This gives us the number of steps we can use forthe interpolation. We refer to the average number of increments as interpolation
steps. The time it takes to increment the counter once equals the resolution
we are able to recover. It can be approximated by dividing the time differenceof two clock edges by the number of interpolation steps. This makes the timer
independent from both the internal and the provided resolution.
The measurement with the improved resolution works as follows. We busy
wait until we observe a clock edge. At this point, we start with the operation
we want to time. After the timed operation has finished, we again busy wait for
the next clock edge while incrementing a counter. We assume that the increment
operation is a constant time operation, thus allowing us to linearly interpolate
the passed time. From the calibration, we know the time of one interpolation stepM. Schwarz, C. Maurice, D. Gruss, S. Mangard
fslow
ffast

Padding
Padding

Fig. : Edge thresholding: apply padding such that the slow function crosses one
more clock edge than the fast function.
which will be a fraction of the provided resolution. Multiplying this time by the
number of increments results in the interpolated time. Adding the interpolated
time to the measured time increases the timer’s resolution again.
Using this method, we recover a highly accurate timestamp. Listing A. shows
the JavaScript implementation. Table shows the recovered resolution for various
values of provided resolution. Even for a timer rounded down to a multiple of
100 ms, we recover a resolution of 15 µs.
Edge thresholding We do not require an exact timestamp in all cases. For
many side-channel attacks it is sufficient to distinguish two operations ffast andfslow based on their execution time. We refer to the execution times of the shortrunning function and long-running function as tfast and tslow respectively.
We devise a new method that we call edge thresholding. This method again
relies on the property that we can execute multiple constant-time operations
between two edges of the clock. Edge thresholding works as long as the differencein the execution time is larger than the time it takes to execute one such constanttime operation. Figure illustrates the main idea of edge thresholding. Using
multiple constant-time operations, we generate a padding after the function wewant to measure. The execution time of the padding tpadding is included into themeasurement, increasing the total execution time by a constant value. The sizeof the padding depends on the provided resolution and on the execution time of
the functions. We choose the padding in such a way that tslow + tpadding crosses
one more clock edge than tfast + tpadding , i.e., both functions take a different
amount of clock edges.
To choose the correct padding, we start without padding and increase thepadding gradually. We align the function start at a clock edge and measure thenumber of clock edges it takes to execute the short-running and the long-running
function. As soon as the long-running function crosses one more clock edge than
the short-running function, we have found a working padding. Subsequently,
this padding is used for all execution time measurements. Figure shows theresults of classifying two functions with an execution time difference of 0.9 µs
and a provided resolution of 10 µs. A normal, unaligned measurement is able toclassify the two functions only in the case when one of the measurements crosses
a clock edge, whereas the edge thresholding method categorizes over 80% of thefunction calls correctly by their relative execution time. Moreover, there are no
false classifications.

percentage

Fantastic Timers and Where to Find Them

100
50
0

100

87

13

0

0

unaligned
both correct82

0alignedfslow misclassified

18

0

paddedffast misclassified

Fig. : Results of edge thresholding where the difference between the function’s
execution time is less then the provided resolution.
.

Alternative timing primitives

In cases where the High Resolution Time API [ ] is not available, e.g., on
Tor browser, we have to resort to different timing primitives, as highlighted by
Kohlbrenner et al. [ ]. As there is no different high-resolution timer available in
JavaScript and we cannot access any native timers, we have to create our own
timing sources. In most cases, it is sufficient to have a fast-paced monotonicallyincreasing counter as a timing primitive that is not a real representation of time
but an approximation of a highly accurate monotonic timer. While this concept
was already presented by Wray in[ ], Lipp et al. [ ] recently demonstrated a practical high-resolution timing primitive on ARM using a counting
thread. As JavaScript is inherently based on a single threaded event loop withno true concurrency, the timing primitive has to be based either on recurring
events or non-JavaScript browser features.
We present several novel methods to construct timing primitives in JavaScript. We refer to them as free-running timers and blocking timers. Free-running
timers do not depend on the JavaScript’s event loop and run independently fromthe remaining code. Blocking timers are based on JavaScript events and are either only usable to recover a high resolution or in combination with web workers.
If used in combination with web workers, the timers become free-running timers.
At first, it seems that timing primitives blocking the JavaScript event loop
might not be useful at all. The higher the resolution of the timing primitive,
the more events are added to the event queue and the less time remains for
actual code. However, there are still two constructions that are able to use suchprimitives. First, these primitives can be used for very accurate interpolation
steps when applying either clock interpolation or edge thresholding. Second, it
is possible to take advantage of the multithreading support with web workers to
run the timing primitive in parallel to the method to time.
Timeouts The first asynchronous feature dating back to the introduction of JavaScript is the WindowTimers API. Specifically the setTimeout and setInterval
functions allow scheduling a timer-based callback. The time is specified in a mil-M. Schwarz, C. Maurice, D. Gruss, S. Mangard

lisecond resolution. After specifying the timeout, the browser keeps track of thetimer and calls the callback as soon as the timer has expired.
A concurrent timer-based callback allows us to simulate a counting thread.
We create a callback function that increments a global counter and schedules
itself again using the setTimeout function. This method has also been used
in a concurrent work [ ]. Although the minimal supported timeout is , thereal timeout is usually larger. The HTML specification defines a timeout of atleast 4 ms for nested timers, i.e., specifying the timeout from within the callback
function has a delay of at least 4 ms [ ]. This limitation also applies to timeouts
specified by the setInterval function.
Most browsers comply to the HTML specification and treat all timeouts below 4 ms as 4 ms. In Firefox, the minimum timeout is determined by the value ofthe flag dom.min_timeout_value which defaults to 4 ms as well. Note that the
timeout only has such a high frequency if it is run in an active tab. Backgroundtasks do not allow such high frequencies.
Microsoft implemented another timeout function in their browsers which
is not standardized. The setImmediate function behaves similarly to thesetTimeout function with a timeout of . The function is not limited to 4 ms andallows to build a high-resolution counting thread. A counting thread using thisfunction results in a resolution of up to 50 µs which is three orders of magnitude
higher than the setTimeout method.
Message passing By default, the browser enforces a same-origin policy, i.e.,
scripts are not allowed to access web page data from a page that is served froma different domain. JavaScript provides a secure mechanism to circumvent thesame-origin policy and to allow cross-origin communication. Scripts can installmessage listeners to receive message events from cross-origin scripts. A scriptfrom a different origin is allowed to post messages to a listener.
Despite the intended use for cross-origin communication, we can use thismechanism within one script as well. The message listener is not limited to messages sent from cross-origin scripts. Neither is there any limitation for the targetof a posted message. Adding checks whether a message should be handled is left
to the JavaScript developer. According to the HTML standard, posted messages
are added to the event queue, i.e., the message will be handled after any pending event is handled. This behavior leads to a nearly immediate execution of theinstalled message handler. A counting thread using the postMessage functions
achieves a resolution of up to 35 µs. An implementation is shown in Listing A. .
To obtain a free-running timing primitive, we have to move the message
posting into separate web workers. This appears to be a straightforward task.
However, there are certain limitations for web workers. Web workers cannot post
messages to other web workers (including themselves). They can only post messages to the main thread and web workers they spawn, so called sub workers.
Posting messages to the main thread again blocks the main thread’s event loop,
leaving sub web workers as the only viable option. Listing A. shows a sample
implementation using one worker and one sub worker. The worker can communi-

Fantastic Timers and Where to Find Them

cate with the main thread and the sub worker. If the worker receives a message
from the main thread, it sends back its current counter value. Otherwise, theworker continuously “requests” the current counter value from the sub worker.
The sub worker increments the counter on each request and sends the current
value back to the worker. The resulting resolution is even higher than with theblocking version of the method. On Tor browser, the achieved resolution is up
to 15 µs, which is orders of magnitude higher than the resolution of the native
timer.
An alternative to sub workers are broadcast channels. Broadcast channels
allow the communication between different sources from the same origin. A
broadcast channel is identified by its name. In order to subscribe to a channel, a worker can create a BroadcastChannel object with the same name as anexisting channel. A message that is posted to the broadcast channel is received
by all other clients subscribed to this broadcast channel. We can build a construct that is similar to the sub worker scenario using two web workers. The
web workers broadcast a message in their broadcast receiver to send the countervalue back and forth. One of the web workers also responds to messages fromthe main thread to return the current counter value. With a resolution of up to
55 µs, this method is still almost as fast as the worker thread variant.
Message Channel The Channel Messaging API provides bi-directional pipes
to connect two clients. The endpoints of the pipe are called ports, and every port
can both send and receive data. A message channel can be used in a similar way
as cross-origin message passing. Listing A. shows a simple blocking counting
thread using a message channel.
As with the cross-origin message passing method, we can also adapt this code
to work inside a web worker yielding a free-running timing primitive. Listing A.
shows the implementation for web workers. The resolution for the free-runningmessage channel method is up to 30 µs, which is lower compared to the crossorigin communication method. However, it is currently the only method thatworks across browsers and has a resolution in the order of microseconds.
CSS animations With CSS version , the support for animations [ ] wasadded. These animations are independent of JavaScript and are rendered by thebrowser. Users can specify keyframes and attributes that will then be animatedwithout any further user interaction.
We demonstrate a new method that uses CSS animations to build a timing primitive. A different method using CSS animations has been used in a
concurrent work [ ]. We define an animation that changes the width of an element from 0 px to 1 000 000 px within 1 s. Theoretically, if all animation steps
are calculated, the current width is incremented every microsecond. However,browsers limit the CSS animations to 60 fps, i.e., the resolution of our timing
primitive is 16 ms in the best case. Indeed, most monitors have a maximum refresh rate of 60 Hz, i.e., they cannot display more than 60 fps. Thus, a higher
frame rate would only waste resources without any benefit. To get the current

M. Schwarz, C. Maurice, D. Gruss, S. Mangard

timestamp, we retrieve the current width of the element. In JavaScript, we canget the current width of the element using window.getComputedStyle(elem,null).getPropertyValue("width").
SharedArrayBuffer Web workers do not have access to any shared resource.
The communication is only possible via messages. If data is passed using amessage, either the data is copied, or the ownership of the data is transferred.
This design prevents race conditions and locking problems without having todepend on a correct use of locks. Due to the overhead of message passing forhigh-bandwidth applications, approaches for sharing data between workers are
discussed by the ECMAScript committee [ ]. An experimental extension forweb workers is the SharedArrayBuffer. The ownership of such a buffer can beshared among multiple workers, which can access the buffer simultaneously.
A shared resource provides a way to build a real counting thread with anegligible overhead compared to a message passing approach. This already raised
concerns with respect to the creation of a high-resolution clock [ ]. In thismethod, one worker continuously increments the value of the buffer without
checking for any events on the event queue. The main thread simply reads thecurrent value from the shared buffer and uses it as a high-resolution timestamp.
We implemented a clock with a parallel counting thread using the SharedArrayBuffer. An implementation is shown in Listing A. . The resulting resolution
is close to the resolution of the native timestamp counter. On our Intel Core itest machine, we achieve a resolution of up to 2 ns using the shared array buffer.
This is equivalent to a resolution of only CPU cycles, which is orders ofmagnitude better than the timestamp provided by performance.now.
.

Evaluation

We evaluated all methods on an Intel Core i U machine using the mostpopular browsers, up to date at the time of writing: Firefox , Chrome , Edge.
. . , and Tor . . . All tests were run on Ubuntu . , Windows ,and Mac OS X . . . Table shows the timing resolution of every method forevery browser and operating system combination. We also evaluated our methods
using Fuzzyfox [ ], the fork of Firefox hardened against timing attacks [ ].
The introduction of multithreading in JavaScript opened several possibilities
to build a timing primitive that does not rely on any provided timer. By building
a counting thread, we are able to get a timer resolution of several microseconds.
This is especially alarming for the Tor browser, where the provided timer only has
a resolution of 100 ms. Using the demonstrated methods, we can build a reliable
timer with a resolution of up to 15 µs. The lower resolution was implemented asa side channel mitigation and is rendered useless when considering the results of
the alternative timing primitives.
The best direct timing source we tested is the experimental SharedArrayBuffer. The best measurement method we tested is edge thresholding. Bothincrease the resolution by at least orders of magnitude compared to performance.now in all browsers. Countermeasures against timing side-channels usingFantastic Timers and Where to Find Them

Ed
ge

To
r

Fu
z

zyf
ox

Ch
ro m
e

performance.now

3

5 µs

5 µs

1 µs

100 ms

100 ms

CSS animations
setTimeout
setImmediate
postMessage
Sub worker
Broadcast Channel
MessageChannel
MessageChannel (W)SharedArrayBuffer

3

16 ms
4 ms
–
45 µs
20 µs
145 µs
12 µs
75 µs
2 ns

16 ms
4 ms
–
35 µs
–
–
55 µs
100 µs
15 ns

16 ms
2 ms
50 µs
40 µs
50 µs
–
20 µs
20 µs
–

16 ms
4 ms
–
40 µs
15 µs
55 µs
20 µs
30 µs
–

125 ms
100 ms–47 ms–
760 µs45 ms1120 µs
2 ns

500 ns2 ns

500 ns15 ns

350 ns
10 ns

15 µs
2 ns

–
–

Freerunning

Interpolation
Edge thresholding

3
3
3
3

efo
x
Fir

. .

Table : Timing primitive resolutions on various browsers and operating systems.

fuzzy time have been proposed by Hu et al. [ ] and Vattikonda et al. [ ].
They suggested to reduce the provided resolution and to randomize the clock
edges. However, we can fall back to the constructed timing primitives if thiscountermeasure is not applied on all implicit clocks.
In a concurrent work, Kohlbrenner et al. [ ] proposed Fuzzyfox, a fork ofFirefox that uses fuzzy time on both explicit and implicit clocks, and aims tocap all clocks to a resolution of 100 ms. Our evaluation shows that the explicit
timer performance.now is reduced to 100 ms, and is fuzzed enough that theinterpolation and edge thresholding methods do not work to recover a high resolution. Similarly, some of the implicit timers, such as setTimeout, postMessage,and Message Channel, are also mitigated, with a resolution between 45 ms and
100 ms. However, the Broadcast Channel, Message Channel with web workers,
and SharedArrayBuffer still have a fine grained resolution, between 2 ns and 1 ms.
It is to be noted that, while these methods stay accurate, the resulting clock is
too fuzzy to derive a finer clock with either interpolation or edge thresholding.

Uses performance.now for coarse-grained timing information.
Sub workers do not work in Chrome, this is a known issue since[ ].
Currently only available in the nightly version.
It has to be enabled by starting Chrome with –js-flags=–harmony-sharedarraybuffer–enable-blink-feature=SharedArrayBuffer.

Number of cases

M. Schwarz, C. Maurice, D. Gruss, S. Mangard
300

cache hitcache miss

200
100
300

350

400
450
500
550
600
650
Access time [SharedArrayBuffer increments]

700

750

Fig. : Histogram for cache hits and cache misses.

Reviving and Extending Microarchitectural Attacks
In this section, we demonstrate that with our timing primitives, we are able torevive attacks that were thought mitigated, and build new DRAM-based attacks.
.

Reviving Cache Attacks

Oren et al. [ ] presented the first microarchitectural side-channel attack running
in JavaScript. Their attack was mitigated by decreasing the timer resolution.
We verified that the attack indeed does not work anymore on current browser
versions. However, we are able to revive cache attacks by using our newly discovered timing sources. Figure shows the timing difference between cache hits
and cache misses, measured with the SharedArrayBuffer method. The ability
to measure this timing difference is the building block of all cache attacks.
.

A New DRAM-based Covert Channel

Pessl et al. [ ] established that timing differences in memory accesses can be
exploited to build a cross-CPU covert channel. We demonstrate that this attack
is also possible using JavaScript. In our scenario, the sender is an unprivileged
binary inside a VM without a network connection. The receiver is implemented
in sandboxed JavaScript running in a browser outside the VM, on the same host.
Overview To communicate, the sender and the receiver agree on a certain bankand row of physical memory. This agreement can be done in advance and is notpart of the transmission. The receiver continuously measures the access time toa value located inside the agreed row. For continuous accesses, the value will becached in the row buffer and the access will be fast, resulting in a low access time.
The receiver considers this as a . If the sender wants to transmit a , it accesses
a different row inside the same bank. This access triggers a row conflict, resulting
in a replacement of the row buffer content. On the receiver’s next access, therequest cannot be served from the row buffer but has to be fetched from the
DRAM, resulting in a high access time.

Fantastic Timers and Where to Find Them

Challenges For the sender, we assume that we can run arbitrary unprivileged
binary programs inside the VM. We implement the sender in C, which allows us
to use the computer’s high-resolution timestamp counter. Furthermore, we canflush addresses from the cache using the unprivileged clflush instruction. The
only limitation on the sender is the absence of physical addresses.
On the receiver side, as the covert channel relies on timing differences thatare in the order of tens of nanoseconds, we require a high-resolution timing
primitive. We presented in Section different methods to build timing primitives if the provided High Resolution Time API is not accurate enough. However, implementing this side channel in JavaScript poses some problems besides
high-resolution timers. First, the DRAM mapping function requires the physicaladdress to compute the physical location, i.e., the row and the bank, inside the
DRAM. However, JavaScript does not know the concept of pointers. Therefore,
we neither have access to virtual nor physical addresses. Second, we have toensure that memory accesses will always be served from memory and not thecache, i.e., we have to circumvent the cache. Finally, the noise present on thesystem might lead to corrupt transfers. We have to be able to detect such bit
inversions for reliable communication.
Address selection The DRAM mapping function reverse engineered by Pessl
et al. [ ] takes a physical address and calculates the corresponding physicalmemory location. Due to the absence of addresses in JavaScript, we cannot
simply use these functions. We have to rely on another side channel to be able
to infer address bits in JavaScript.
We exploit the fact that heap memory in JavaScript is allocated on demand,i.e., the browser acquires additional heap memory from the operating system if
this is required. These heap pages are internally backed by 2 MB pages, called
Transparent Huge Pages (THP). Due to the way virtual memory works, for
THPs, theleast-significant bits of a virtual and physical address are thesame. On many systems, this is already sufficient as input to the DRAM mapping
function. This applies to the sender as well, with the advantage that we know
the virtual address which we can use immediately without any further actions.
To get the beginning of a THP in JavaScript, we iterate through an arrayof multiple megabytes while measuring the time it takes to access the arrayelement, similarly to Gruss et al. [ ]. As the physical pages for these THPs arealso mapped on-demand, a page fault occurs as soon as an allocated THP isaccessed for the first time. Such an access takes significantly longer than anaccess to an already mapped page. Thus, higher timings for memory accesses
with a distance of 2 MB indicate the beginning of a THP. At this array index,
theleast-significant bits of both the virtual and the physical address are .
Cache circumvention To measure DRAM access times we have to ensure that
all our accesses go to the DRAM and not to the cache. In native code, we canrely on the clflush instruction. This unprivileged instruction flushes a virtualM. Schwarz, C. Maurice, D. Gruss, S. Mangard

address from all cache levels, i.e., the next access to the address is ensured to
go to the DRAM.
However, in JavaScript we neither have access to the clflush instruction nor
does JavaScript provide a function to flush the cache. Thus, we have to resort tocache eviction. Cache eviction is the process of filling the cache with new data
until the data we want to flush is evicted from the cache. The straightforward
way is to fill a buffer with the size of the last-level cache with data. However,this is not feasible in JavaScript as writing multiple megabytes of data is too
slow. Moreover, on modern CPUs, it might not suffice to iteratively write to thebuffer as the cache replacement policy is not pseudo-LRU since Ivy Bridge [ ].
Gruss et al. [ ] demonstrated fast cache eviction strategies for numerous
CPUs. They showed that their functions have a success rate of more than 99.75%
when implemented in JavaScript. We also rely on these functions to evict theaddress which we use for measuring the access time.
Transmission To transmit data from inside the VM to the JavaScript, they
have to agree on a common bank. It is not necessary to agree on a bank dynamically, it is sufficient to have the bank hardcoded in both programs. The senderand the receiver both choose a different row from this bank. Again, this can be
hardcoded, and there is no requirement for an agreement protocol.
On the sender side, the application inside the VM continuously accesses amemory address in its row if it wants to transmit a binary . These accesses cause
row conflicts with the receiver’s row. To send a binary , the sender does nothing
to not cause any row conflict. On the receiver side, the JavaScript constantly
measures the access time to a memory address from its row and evicts the address
afterwards. If the sender has accessed its row, the access to the receiver’s row
results in a row conflict. As a row conflict takes significantly longer than a row
hit, the receiver can determine if the sender has accessed its row.
To synchronize sender and receiver, the receiver measures the access time in ahigher frequency than the sender is sending. The receiver maintains a constantsize sliding window that moves over all taken measurements. As soon as the
majority of the measurements inside the sliding window is the same, one bit
is received. The higher the receiver’s sampling frequency is, compared to thesender’s sending frequency, the lower the probability of wrongly measured bits.
However, a higher sampling frequency also leads to a slower transmission speed
due to the increased amount of redundant data.
Due to different noise sources on the system, we encounter transmission errors. Such noise sources are failed evictions, high DRAM activity of other programs or not being scheduled at all. To have a reliable transmission despite
those interferences, we encapsulate the data into packets with sequence numbers and protect each packet with an error detection code as shown in Figure .
The receiver is then able to detect any transmission error and to discard thepacket. The sequence number ensures to keep the data stream synchronized.
Thus, transmission errors only result in missing data, but the data stream isFantastic Timers and Where to Find Them
Data

EDC

S
E
Q

Fig. : One packet of the covert channel. It has a -bit preamble “ ”,
bits, bits of error detection code and a bit sequence number.

datastill synchronized after transmission errors. To deal with missing data, we canapply high-level error correction as shown by Maurice et al. [ ].
Using the SharedArrayBuffer, we achieve a transmission rate of 11 bps for a
3 kB file with an error rate of 0% on our Intel Core i test machine. The system
workload did not influence the transmission, as long as there is at least one
core fully available to the covert channel. We optimized the covert channel for
reliability and not speed. We expect that it is possible to further increase thetransmission rate by using multiple banks to transmit data in parallel. However,the current speed is two orders of magnitude higher than the US government’s
minimum standard for covert channels [ ].

Countermeasures
Lowering the timer resolution As a reaction to the JavaScript cache attacks published by Oren et al. [ ], browsers reduced the resolution of the highresolution timer. Nevertheless, we are able to recover a higher resolution fromthe provided timer, as well as to build our own high-resolution timers.
Fuzzy time Vattikonda et al. [ ] suggested the concept of fuzzy time to get
rid of high-resolution timers in hypervisors. Instead of rounding the timestamp
to achieve a lower resolution, they move the clock edge randomly within one
clock cycle. This method prevents the detection of the underlying clock edge
and thus makes it impossible to recover the internal resolution. In a concurrent
work, Kohlbrenner et al. [ ] implemented the fuzzy time concept in Firefox
to show that this method is also applicable in JavaScript. The implementation
targets explicit clocks as well as implicit clocks. Nonetheless, we found different
implicit clocks exceeding the intended resolution of 100 ms.
Shared memory and message passing A proposed mitigation is to introduce thread affinity to the same CPU core for threads with shared memory [ ].
This prevents true parallelism and should therefore prevent a real asynchronous
timing primitive. However, we showed that even without shared memory wecan achieve a resolution of up to 15 µs by using message passing. Enforcing theaffinity to one core for all communicating threads would lead to a massive performance degradation and would effectively render the use of web workers useless.
A compromise is to increase the latency of message passing which should notaffect low- to moderate-bandwidth applications. Compared to Fuzzyfox’s delay

M. Schwarz, C. Maurice, D. Gruss, S. Mangard

on the main event queue, this has two advantages. First, the overall usability
impact is not as severe as only messages are delayed and not every event. Second, it also prevents the high accuracy of the Message Channel and Broadcast
Channel method as the delay is not limited to the main event queue.

Conclusion and Outlook
High-resolution timers are a key requirement for side-channel attacks in browsers.
As more side-channel attacks in JavaScript have been demonstrated against
users’ privacy, browser vendors decided to reduce the timer resolution.
In this article, we showed that this attempt to close these vulnerabilities was
merely a quick-fix and did not address the underlying issue. We investigated different timing sources in JavaScript and found a number of timing sources witha resolution comparable to performance.now. This shows that even removing
the interface entirely, would not have any effect. Even worse, an adversary canrecover a resolution of the former performance.now implementation throughmeasurement methods we proposed. We evaluated our new measurement methods on all major browsers as well as the Tor browser that has applied the highest
penalty to the timer resolution. Our results are alarming for all browsers, including the privacy-conscious Tor browser, as we are able to recover a resolution in
the order of nanoseconds in all cases. In addition to reviving attacks that were
now deemed infeasible, we demonstrated the first DRAM-based side channel
in JavaScript. In this side-channel attack, we implemented a covert channel between an unprivileged binary in a VM with no network interface and a JavaScript
program in a browser outside the VM, on the same host.
While fuzzy timers can lower the resolution of the provided timer interfaces,
we show that applying the same mitigation on all implicit clocks, including theone that are not discovered yet, is a complex task. Thus, we conclude that it islikely that an adversary can obtain sufficiently accurate timestamps when running arbitrary JavaScript code. As microarchitectural attacks are not restricted
to JavaScript, we recommend to mitigate them at the system- or hardware-level.

Acknowledgments
We would like to thank our shepherd Jean Paul Degabriele, Georg Koppen from the Tor Browser project as well as all our anonymous reviewers.
We would also like to thank the major browser vendors for their quick
responses when reporting our findings. This project has received funding
from the European Research Council (ERC) under
the European Union’s Horizon
research and innovation programme (grant agreement No).

Fantastic Timers and Where to Find Them

References. Alex Christensen: Reduce resolution of performance.now. https://bugs.webkit.
org/show_bug.cgi?id=(). Bernstein, D.J.: Cache-Timing Attacks on AES. http://cr.yp.to/antiforgery/cachetiming.pdf (). Boris Zbarsky: Reduce resolution of performance.now. https://hg.mozilla.org/
integration/mozilla-inbound/rev/ ae b e ab
. Bortz, A., Boneh, D.: Exposing private information by timing web applications.
In: WWW’ (). Bosman, E., Razavi, K., Bos, H., Giuffrida, C.: Dedup Est Machina: Memory Deduplication as an Advanced Exploitation Vector. In: S&P’ (). Chromium: window.performance.now does not support sub-millisecond precision on Windows. https://bugs.chromium.org/p/chromium/issues/detail?id=#c(). Chromium Bug Tracker: HTML nested workers are not supported in chromium.
https://bugs.chromium.org/p/chromium/issues/detail?id=(), retrieved on October ,. Felten, E.W., Schneider, M.A.: Timing attacks on web privacy. In: CCS’ (). Gruss, D., Maurice, C., Mangard, S.: Rowhammer.js: A Remote Software-Induced
Fault Attack in JavaScript. In: DIMVA’ (). Gullasch, D., Bangerter, E., Krenn, S.: Cache Games – Bringing Access-Based
Cache Attacks on AES to Practice. In: S&P’ (). Heiderich, M., Niemietz, M., Schuster, F., Holz, T., Schwenk, J.: Scriptless attacks: stealing the pie without touching the sill. In: Proceedings of the
ACM
conference on Computer and communications security. pp.
– . ACM (). Hu, W.M.: Lattice Scheduling and Covert Channels. In: S&P’ . pp. – (). Jang, D., Jhala, R., Lerner, S., Shacham, H.: An empirical study of privacyviolating information flows in javascript web applications. In: CCS’ (). Jia, Y., Dong, X., Liang, Z., Saxena, P.: I know where you’ve been: Geo-inference
attacks via the browser cache. IEEE Internet Computing ( ), – (). Kim, Y., Daly, R., Kim, J., Fallin, C., Lee, J.H., Lee, D., Wilkerson, C., Lai, K.,
Mutlu, O.: Flipping bits in memory without accessing them: An experimental studyof DRAM disturbance errors. In: ISCA’ (). Kocher, P.C.: Timing Attacks on Implementations of Diffe-Hellman, RSA, DSS,
and Other Systems. In: Crypto’ . pp.
–(). Kohlbrenner, D., Shacham, H.: Fuzzyfox. https://github.com/dkohlbre/geckodev/tree/fuzzyfox (), retrieved on January ,. Kohlbrenner, D., Shacham, H.: Trusted browsers for uncertain times. In: USENIX
Security Symposium (). Lars T Hansen: Shared memory: Side-channel information leaks. https://github.
com/tc /ecmascript_sharedmem/blob/master/issues/TimingAttack.md(). Lipp, M., Gruss, D., Spreitzer, R., Maurice, C., Mangard, S.: ARMageddon: Cache
Attacks on Mobile Devices. In: USENIX Security Symposium (). Liu, F., Yarom, Y., Ge, Q., Heiser, G., Lee, R.B.: Last-Level Cache Side-Channel
Attacks are Practical. In: S&P’ (). Martin, R., Demme, J., Sethumadhavan, S.: TimeWarp: Rethinking timekeeping and performance monitoring mechanisms to mitigate side-channel attacks.
In: Proceedings of theth International Symposium on Computer Architecture(ISCA’ ) ()

M. Schwarz, C. Maurice, D. Gruss, S. Mangard. Maurice, C., Neumann, C., Heen, O., Francillon, A.: C : Cross-Cores Cache Covert
Channel. In: DIMVA’ (). Maurice, C., Weber, M., Schwarz, M., Giner, L., Gruss, D., Alberto Boano, C.,
Mangard, S., Römer, K.: Hello from the Other Side: SSH over Robust Cache Covert
Channels in the Cloud. In: NDSS’ (), to appear. Mike Perry: Bug: Reduce precision of time for Javascript. https://gitweb.
torproject.org/user/mikeperry/tor-browser.git/commit/?h=bug(). Mozilla Developer Network: Concurrency model and Event Loop. https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop (). Mozilla Inc.: Ecmascript shared memory and atomics. http://tc .github.io/
ecmascript_sharedmem/shmem.html (). 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’()
. Osvik, D.A., Shamir, A., Tromer, E.: Cache Attacks and Countermeasures: theCase of AES. In: CT-RSA(). Page, D.: Theoretical use of cache memory as a cryptanalytic side-channel. Cryptology ePrint Archive, Report/(). Percival, C.: Cache missing for fun and profit. In: Proceedings of BSDCan (). Pessl, P., Gruss, D., Maurice, C., Schwarz, M., Mangard, S.: DRAMA: Exploiting DRAM Addressing for Cross-CPU Attacks. In: USENIX Security Symposium(). 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’(). Seaborn, M.: Comment on ecmascript shared memory and atomics. https://github.
com/tc /ecmascript_sharedmem/issues/ #issuecomment(). Stone, P.: Pixel perfect timing attacks with html . Context Information Security(White Paper) (). U.S. Department of Defense: Trusted computing system evaluation "the orange
book". Technical Report. -STD (). Van Goethem, T., Joosen, W., Nikiforakis, N.: The clock is still ticking: Timing
attacks in the modern web. In: CCS’ (). Vattikonda, B.C., Das, S., Shacham, H.: Eliminating fine grained timers in xen.
In: CCSW’ (). W C: CSS Animations. https://www.w .org/TR/css -animations/ (). W C: High Resolution Time Level . https://www.w .org/TR/hr-time/ (). 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’ (). WHATWG: HTML Living Standard – Timers. https://html.spec.whatwg.org/
multipage/webappapis.html#timers (), retrieved on October ,. Wong, H.: Intel Ivy Bridge Cache Replacement Policy. http://blog.stuffedcow.
net// /ivb-cache-replacement/, retrieved on October ,. Wray, J.C.: An analysis of covert timing channels. Journal of Computer Security( - ),–(). Wu, Z., Xu, Z., Wang, H.: Whispers in the Hyper-space: High-bandwidth andReliable Covert Channel Attacks inside the Cloud. IEEE/ACM Transactions on
Networking (). Xiao, J., Xu, Z., Huang, H., Wang, H.: A covert channel construction in a virtualized environment. In: CCS’ ()

Fantastic Timers and Where to Find Them
. Xu, Y., Bailey, M., Jahanian, F., Joshi, K., Hiltunen, M., Schlichting, R.: An
exploration of L cache covert channels in virtualized environments. In: CCSW’(). Yarom, Y., Falkner, K.: Flush+Reload: a High Resolution, Low Noise, L Cache
Side-Channel Attack. In: USENIX Security Symposium ()

A

JavaScript Codefunction calibrate (){var counter = , next ;f o r ( var i = ; i <; i ++){
n e x t = wait_edge ( ) ;c o u n t e r += count_edge ( ) ;}n e x t = wait_edge ( ) ;r e t u r n ( wait_edge ( ) - n e x t ) /( counter /. );}f u n c t i o n measure ( f n c ){v a r s t a r t = wait_edge ( ) ;fnc () ;v a r count = count_edge ( ) ;r e t u r n ( p e r f o r m a n c e . now ( ) - s t a r t )- count * c a l i b r a t e ( ) ;}a: Clock interpolation.

f u n c t i o n wait_edge ( ){v a r next , l a s t =p e r f o r m a n c e . now ( ) ;while ( ( next =p e r f o r m a n c e . now ( ) )== l a s t ) {}r e t ur n next ;}f u n c t i o n count_edge ( ){var l a s t = performance .
now ( ) , count = ;w h i l e ( p e r f o r m a n c e . now ( )== l a s t ) count++;r e t u r n count ;}b: Helper functions.

Listing A. : Clock interpolation: calibrate returns the time one increment takes,
measure uses interpolation to measure the execution time of fnc

v a r count =;function counter (){count++;
window . p o s t M e s s a g e ( n u l l , window . l o c a t i o n ) ;}window . a d d E v e n t L i s t e n e r ( " message " , c o u n t e r ) ;window . p o s t M e s s a g e ( n u l l , window . l o c a t i o n ) ;Listing A. : Abusing cross-origin communication to build a counting thread.

M. Schwarz, C. Maurice, D. Gruss, S. Mangard

v a r t s = newWorker ( ’ subworker . j s ’ ) ;t s . postMessage ( ) ;function counter ( event ){timestamp = e v e n t . d a t a ;}t s . a d d E v e n t L i s t e n e r ( " message " ,counter ) ;[...]// g e t timestamp
t s . postMessage ( ) ;a: Timing measurement example.
v a r count =;onmessage = f u n c t i o n ( e v e n t ){count++;
p o s t M e s s a g e ( count ) ;}v a r sub = newWorker ( " subworker . j s " ) ;sub . p o s t M e s s a g e ( ) ;v a r count =;sub . onmessage = msg ;onmessage = msg ;f u n c t i o n msg ( e v e n t ){i f ( e v e n t . d a t a != ){count = e v e n t . d a t a ;sub . p o s t M e s s a g e ( ) ;}else
s e l f . postMessage (count ) ;}c: subworker.js

b: subworker .js
Listing A. : Message passing with web workers to get a free-running timer.

v a r count = , c h a n n e l = n u l l ;f u n c t i o n handleMessage ( e ){count++;
channel . port . postMessage ( ) ;}c h a n n e l = new MessageChannel ( ) ;c h a n n e l . p o r t . onmessage = h a n d l e M e s s a g e ;channel . port . postMessage ( ) ;Listing A. : A blocking timing primitive using a message channel.

Fantastic Timers and Where to Find Themv a r worker = newWorker ( " mcworker . j s " ) ;v a r main_channel = new
MessageChannel ( ) ;v a r s i d e _ c h a n n e l = new
MessageChannel ( ) ;f u n c t i o n handleMessage ( e ){timestamp = e . d a t a ;}main_channel . p o r t . onmessage =handleMessage ;worker . p o s t M e s s a g e ( ,[ main_channel . p o r t ,side_channel . port ,side_channel . port
]) ;
[...]
// g e t timestamp
main_channel . p o r t . p o s t M e s s a g e( );a: Timing measurement example.

v a r main_port , p o r t , port
count = ;,s e l f . onmessage = f u n c t i o n (event ){
main_port = e v e n t . p o r t s[ ];port = event . ports [ ] ;port = event . ports [ ] ;main_port . onmessage =function (){main_port . p o s t M e s s a g e (count ) ;};p o r t . onmessage =function (){count++;
port . postMessage ( ) ;};p o r t . p o s t M e s s a g e ( count ) ;};b: mcworker.js

Listing A. : Message passing with web workers to get a free-running timer.

v a r b u f f e r = newSharedArrayBuffer ( ) ;v a r c o u n t e r = newWorker ( " c o u n t e r . j s " ) ;counter . postMessage ( [ b u f f e r ] ,[ buffer ]) ;v a r a r r = new
Uint Array ( b u f f e r ) ;[...]timestamp = a r r [];a: Timing measurement example.

s e l f . onmessage = f u n c t i o n (event ){
var [ b u f f e r ] = event . data ;v a r a r r = new
Uint Array ( b u f f e r ) ;while ( ){a r r [ ]++;}}

b: counter.js

Listing A. : Parallel counting thread without additional overhead.