October 1, 2020
We can distinguish two types of clocks – explicit and implicit. Explicit clocks are used by developers to get direct timing measurements, mechanisms of this type are offered explicitly by the browser. In contrast, implicit clocks utilize particular web features to create unintended clocks that allow measuring the relative passage of time.
Explicit Clocks #
performance.now API #
The performance.now() API allows developers to get high-resolution timing measurements.
Date API #
The Date API is the oldest API present in browsers which can be used to obtain timing measurements. It allows developers to get dates, and get Unix timestamps with
Date.now(). These measurements are much less precise than performance.now(). Before the introduction of newer APIs, attacks used to leverage this API 1.
Implicit Clocks #
SharedArrayBuffer and Web Workers #
With the introduction of
Web Workers, new mechanisms to exchange data between threads were created 2. One of those mechanisms is
SharedArrayBuffer which provides memory sharing between the main thread and a worker thread. A malicious website can create an implicit clock by loading a worker running an infinite loop that increments a number in the buffer. This value can then be accessed by the main thread at any time to read how many incrementations were performed.
SharedArrayBufferwas removed from browsers with the publication of Spectre. It was reintroduced later in 2020, requiring documents to be in a secure context to make use of the API. Since secure contexts cannot reference any cross-origin content that has not explicitly opted in to being accessed, this means SharedArrayBuffers cannot be used as clocks for some XS-Leaks.
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
To get the relative time in a main thread, you can use the Atomics API.