Conceptio › Archive › arXiv CS
arXiv CS open access

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

2026 · arxiv_cs
arXiv CS · Papers · 2026
Open Source ↗Direct PDF ↓
cryptographycybersecurityprivacysecurity
Conceptio Open Archive

Analyze & explore related research in Conceptio

Connect this record directly into your research workflow or AI agent. Explore citations across open repositories, query full text, and export structured proof bundles.

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers Martin Schwarzl Cloudflare, Inc. USA

Haocheng Xiao

Sam Ainsworth

arXiv:2608.17043v1 [cs.CR] 17 Aug 2026

University of Edinburgh United Kingdom

Abstract Edge computing solutions have become a crucial part of the industry, delivering fast, flexible and scalable applications close to the end users, with typical use cases including dynamic content creation, image resizing and chatbots. Cloudflare Workers is one such framework, which handles millions of HTTP requests per second across the world. To reduce start-up latency, Cloudflare Workers removes process-isolation boundaries between multiple tenants and leverages language-level isolation. This architecture poses the risk of Spectre attacks. To mitigate these, Cloudflare Workers previously introduced several countermeasures such as restricted timer measurements, no shared memory, no multithreading and Dynamic Process Isolation (DyPrIs), detecting potential attacks and process-isolating potentially malicious scripts. In this paper, we demonstrate that the production implementation of DyPrIs was insufficient. We adopt microarchitectural amplification techniques and discover various possibilities to measure time in the production environment of Cloudflare Workers. Given these techniques, we demonstrate that freezing and coarsening of timers in the security model of Cloudflare Workers is insufficient. Leveraging both timing amplification and remote timers, we demonstrate a remote Spectre attack that leaks a JWT token from a co-located victim worker in the Cloudflare Workers production environment. We outperform the existing attack by orders of magnitude, going from 2 bit/min to up to 12 bit/s at an accuracy of 99.16 %, posing an immediate risk to customer data. Following our demonstration of the end-to-end attack, Cloudflare Workers mitigated it in a coordinated effort by integrating the V8 Sandbox limiting transient access to 64-bit pointers, improving the detection capabilities of DyPrIs, and deploying hardware-assisted MPK-based in-process isolation to confine each tenant heap under a dedicated memory-protection key.

1

Albert Pedersen

University of Edinburgh United Kingdom

Introduction

Edge computing improves modern digital systems by moving data processing closer to users, enabling faster and smoother applications with low delays. This enables a broad spectrum of applications ranging from dynamic content generation to real-time interactive services. Edge-computing solutions process millions of HTTP requests per second across a globally distributed network, and the processed data contains sensitive information such as credentials, API tokens, cryptographic key material, and HTTP form data. Edge-computing providers, such as Cloudflare Workers, use languagelevel isolation [16] to reduce overheads versus process isolation,

Cloudflare, Inc. USA

Nigel Topham

University of Edinburgh United Kingdom caused by long startup times and high context-switching costs [13, 21, 43]. This results in a co-location of thousands of different tenants within the same process, meaning a single vulnerability enabling arbitrary memory reads can lead to massive data leakage [22, 44]. Cloudflare Workers relies on the V8 runtime [13] to enable languagelevel isolation. To minimize the patch gap for memory-safety bugs, the Cloudflare Workers team use automated pipelines [16] to patch V8 vulnerabilities on edge servers. However, side-channel attacks also have to be considered in edge computing systems, where resources are shared [16]. In a singleprocess-multi-tenant systems, Spectre [38] particularly poses a huge memory disclosure risk. In contrast to browser vendors, who gave up on remediating in-process Spectre by introducing process isolation [42, 47], Cloudflare Workers introduced several countermeasures [16]. For example, the high-resolution timer available in JavaScript performance.now has the same coarse resolution as Date.now, with both returning only the time of the last I/O event, otherwise being frozen during execution. There is also no multithreading possible, preventing the introduction of counting threads as well as no shared memory between tenants [16, 53]. Schwarzl et al. [56] previously demonstrated a remote Spectre attack leaking 120 bit/h, leveraging a noisy remote timing source with a limited amount of subrequests. The evaluated amplification technique relied on looping over the gadget with 250 000 repetitions to amplify a single bit. Moreover, to evict a single cache line, a loop over a huge array was performed, which was costly in terms of attack run-time. As a countermeasure, a probabilistic approach called Dynamic Process Isolation (DyPrIs) [56] was introduced, which monitors the performance counters on a per-script base and dynamically isolates malicious-looking scripts into separate processes. This defense was integrated into the production system of Cloudflare Workers. The main assumption of DyPrIs [56] is that the attack is too slow to leak any sensitive data within a timeframe shorter than a measurable detection window of 30 s, and, therefore requires multiple executions. Moreover, the detection assumes that all Spectre attacks form an easily distinguishable signal via performance counters compared to benign production scripts. Given state-of-the-art techniques to efficiently construct precise timers from microarchitectural events [2, 30, 45, 50, 69] the attack has room for improvement. Still, we also identified three challenges to practicality unsolved in the previous attack [56]: (1) C1: Limited Runtime and Co-Location of Worker Scripts. DyPrIs [56] assumes a co-location within a process between

Martin Schwarzl, Haocheng Xiao, Albert Pedersen, Sam Ainsworth, and Nigel Topham

attacker and victim. It is unclear how to repeatedly invoke a script on the same machine and the same process. (2) C2: Remote Timer. The co-located timer in DyPrIs [56] (cf. Sec. 3.1) is assumed possible without proof, and the evaluation was performed in a local-network setup. We demonstrate how to create a stable remote timing source in the production system of Cloudflare Workers. (3) C3: Robustness. The frequent upgrades of the V8 engine in Cloudflare Workers require a version-agnostic proofof-concept. Moreover, Spectre attacks are quite sensitive to systems activity i.e. noise. Thus, techniques to stabilize the attack are required with respect to the just-in time compilation, cache eviction and CPU transient-execution windows. Moreover, DyPrIs is active on the production system and monitors the scripts. Thus, a successful attack requires a leak within a single or a few executions before getting detected and then process isolated. In this paper, we solve the above mentioned challenges and in collaboration with Cloudflare Workers demonstrate a stable endto-end remote Spectre attack. For ethical reasons, the attack only aimed at our own controlled worker scripts and no customer data has been accessed. The attack relies on the core attack primitives such as a remote timer, stable signal amplification, a Spectre gadget and efficient memory eviction. Leveraging WebSockets we construct a remote timer, thereby overcoming the subrequests limit for a single worker invocation [9, 56]. Our experiments show that it is possible to create a co-located remote timer to the attacker script. We evaluate a worker-to-worker WebSocket connection leveraging existing timing source Date.now leading to a median resolution of 1 ms. In addition, we analyze the resolution of a local high-resolution timer, a worker serving the local high-resolution timer via WebSocket connection, a remote timer running on an AWS instance returning high-resolution timestamps, and a timer using the Cloudflare Sandbox SDK co-located with the attacking Worker. We demonstrate that Cloudflare Workers’ Durable Objects feature can be used to co-locate a high-resolution timer on the same physical machine as the attacking Worker, and that the Cloudflare Sandbox SDK enables a native rdtsc-based timer server on the same machine, achieving the highest accuracy of all evaluated timers. We further demonstrate that even with a distance of over 1200 km, a stable timing resolution in the hundreds of microseconds can be achieved. We leverage a feature of Cloudflare Workers’ Durable Objects to circumvent the 30 s CPU runtime limit of a single worker [9]. By using keep-alive signals, an attacker can run a single invocation of a worker script for more than 20 h. Moreover, this feature is helpful to achieve co-location between an attacker and victim within the same process. The attacker compares the machine names in Cloudflare’s /cdn-cgi/trace endpoint. This fact undermines the design assumptions of the defenses in DyPrIs [55]. DyPrIs assumes the need to average the results of multiple invocations. Our attack leaks sensitive data already within the first invocation. The attacker will not be process isolated during execution. This is a fundamental limitation in the capabilities of the detection, as we show that the code paths exercised during WebSocket handling significantly

increase iTLB activity, thereby suppressing the normalized ratio between branch mispredicts and iTLB hit rate, treated as a fingerprint for Spectre activity in DyPrIs [55], allowing the attack to evade detection. To achieve robustness, we present a novel Spectre gadget that is stable across multiple V8 upgrades. We analyze the existing techniques used to perform speculative type confusion in JavaScript. We then enumerate typical challenges that have to be overcome such as cache eviction, memory alignment, high systems utilization and frequent V8 updates. We leverage memory-alignment rules in V8 to enable a successful attack not reliant on cache eviction sets [2, 25, 66]. We evaluate our end-to-end attack in the production environment of Cloudflare Workers. We demonstrate a remote Spectre attack that leaks a JWT token from a co-located victim worker. The attack achieves a leakage rate of up to 12 bit/s, outperforming previously presented attacks [56, 58] by 360×. Given the demonstrated amplification techniques, the freezing and coarsening of timers in the security model of Cloudflare Workers is insufficient. We conclude that the threat of in-process Spectre at Cloudflare Workers is higher than previously evaluated, though the Cloudflare Workers team found no indicators of the vulnerability being actively exploited. Following our demonstration of the end-to-end attack, Cloudflare Workers mitigated it in a coordinated effort by integrating the V8 Sandbox limiting transient access to 64-bit pointers, improving the detection capabilities of DyPrIs, and deploying hardware-assisted Intel-MPK-based in-process isolation to confine each tenant heap under a dedicated memory-protection key [15]. Contributions. The main contributions of this work are: (1) We present techniques to co-locate two worker scripts in production systems of Cloudflare Workers. (2) We re-evaluate remote timers in Cloudflare Workers, showing that high-resolution timers are in fact achievable. (3) We identify limitations of prior Spectre gadgets under remote timers and devise methods to overcome them. (4) We mount successful remote Spectre attacks on Cloudflare Workers, leaking a JWT token from a co-located victim worker at up to 12 bit/s, outperforming previous attacks [56] by 360×. Outline. The remainder of the paper is organized as follows. In Section 2, we provide the necessary background. Section 3 states the threat model of our attack. We demonstrate how we overcome the challenges when using attack primitives from Schwarzl et al. [56] to leak secrets from arbitrary address in Section 4. We evaluate our remote Spectre attack in Section 5, before presenting mitigations in Section 6 and concluding in Section 7.

2

Background and Related Work

This section provides the necessary background for remote timing and Spectre attacks.

2.1

Remote Timing Attacks

To leak information about timing side channels over the internet requires remote timing: the ability to measure execution of a process running on a remote machine. The first remote timing attacks targeted cryptographic primitives [1, 4, 6, 28, 71]. TIME [3] exploits

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

the compression ratio of encrypted data to leak HTTP cookies. Vanhoef et al. [64] demonstrated that timing can be leveraged to infer the size of cross-origin resources in HTTP/2. Van Goethem et al. [63] analyzed sequential timing attacks through various data centers and presented a novel technique exploiting the response order of concurrent packets in HTTP/2 to infer the timing without measuring it. There were several attacks exploiting various side channels in practical settings to remotely exfiltrate data [24, 40, 54, 57, 58]. Wang et al. [67] leveraged DVFS to attack post-quantum cryptography. Kettle [27] recently demonstrated practical web timing attacks differentiating small latencies down to 200 µs.

2.2

Spectre

Speculative execution relies on the outcome of branch prediction to predict the targets of a branch instruction. If the predicted target branch turns out to be wrong, the results have to be discarded, and the correct branch is being executed. However, this rollback does not cleanup the microarchitectural state of data that would never have been accessed under program-order correct execution, e.g. transiently accessed data still being cached, leading to Spectre attacks [7, 38]. In combination with a microarchitectural side channel, the accessed data can then be recovered e.g. via cache latency.

2.3

Spectre in JavaScript

The typical challenge of porting Spectre to JavaScript is to craft a reliable gadget enabling transient out-of-bounds accesses. This gadget needs to open a sufficiently large transient execution window [61] such that data can be both accessed and encoded into a side channel. Given a noisy production system, measurement for a single leaked bit have to be repeatable. Thus, another primitive is required to evict the accessed memory address at least by one cache level in order to measure whether the transient execution re-loads it or not. The original Spectre [38] proof-of-concept provided a JavaScript-based Spectre leaking data from an array. As a consequence, modern browser vendors started reducing the resolution of timers in JavaScript and suggested the use of process isolation for different origins. Roettger and Janc [61] demonstrated a SpectrePHT gadget able to address 32-bit indices relative to a TypedArray via speculative bound checking bypass. At the same time, Johnson [29] designed a portable Spectre exploit working on Safari and Chrome, exploiting hardware-agnostic techniques like pigeonhole eviction and memory-level parallelism to amplify a single event. Ragab et al. [46] demonstrated a transient arbitrary read primitive in Firefox by leveraging machine clears opening a transient execution window and the encoding of floating point values to construct 64-bit pointers. Various works leverage speculative type confusion to construct a transient 64-bit read primitive [2, 35, 56]. Wikner et al. [68] demonstrate an attack exploiting Spectre-RSB in WebAssembly to steal JWT tokens from Blazor applications in Firefox. Kim et al. [34] exploited a Spectre gadget in a more recent V8 version transiently leaking ARM MTE tags. More recently, load value prediction and data value prediction on Apple’s M2 and M3 CPUs were exploited to read sensitive data from Safari and Chrome [32, 33]. In all of these works, TypedArrays such as Uint8Array or Uint32Array are predominantly used due to their memory layout. This layout

enables both index-based memory reads and 64-bit pointer dereferences. Both structures facilitate Spectre gadget construction in prior work and our work (Section 4.4).

2.4

Cloudflare Workers

Cloudflare Workers [13] handles millions of web requests from thousands of tenants around the world. Its single-process design, based on V8 JavaScript isolates, allows it to run multiple thousands of tenants within one process. This design guarantees customers’ high performance demands due to less overhead when context switching between threads. However, this single-process design is susceptible to in-process Spectre attacks, as multiple tenants share the same virtual address space. A free-to-use worker can run for up to 10 ms, and the paid version up to 30 s [9], with longer 15 min runtimes for Cron Trigger and Queue Consumer. To mitigate Spectre attacks, Cloudflare Workers uses several countermeasures [55]. The only available timing function Date.now is only updated after I/O operations are performed and machines are restarted on a daily basis [16]. As a worker is single-threaded, separate timing threads [53] are not possible [16].

2.5

DyPrIs

As a countermeasure to remote Spectre attacks, Dynamic Process Isolation (DyPrIs) [56] was introduced by Cloudflare. The idea of DyPrIs is to monitor performance counters in worker scripts to look for signs of likely Spectre attack. These are normalized by the number of ITLB accesses, and based on a threshold, potentially malicious scripts are isolated into separate processes. Measured performance counters include branch accesses/misses, L1 accesses/misses and L3 accesses/misses [56]. Schwarzl et al. [56] also discuss how the attack can be watered down to bypass detection by reducing L1 accesses and increasing iTLB accesses, but only at bitrates of 1 bit/h, which were thought to make the attack infeasible given a 30-second run-time limit.

2.6

Bypassing Timing Mitigations

A major challenge to create a robust Spectre attack in a production system like Cloudflare Workers is reliable signal amplification, such that the remote timers’ coarse resolution can be overcome. Prior work has explored several approaches based on repetition, amplification gadgets, and multi-sampling. Execution repetition [42, 56] accumulates timing differences by triggering the same leak repeatedly. While applicable to most scenarios, the accumulation speed is slow [42, 45] because most of the runtime is spent on triggering the leakage itself. For example, Schwarzl et al. [56] achieved a leakage rate of only 120 bit/h with pure repetition. Higher amplification rates are achieved by amplification gadgets. Röttger and Janc [50] introduced PLRU-based amplification, exploiting L1D cache replacement policies to cause many cache misses from a single state change, without repeated leakage triggers. Hacky Racers [69] generalizes this approach and proposes further amplification gadgets based on Instruction-Level Parallelism. However, these gadgets rely on delicate microarchitectural state that is prone to invalidation by system interrupts, limiting the achievable timing difference to less than 0.5 ms. Purnal et al. [45] achieve timing differences up to 5 ms, and up to 350 ms with prefetch instructions. Transient-execution-based

Martin Schwarzl, Haocheng Xiao, Albert Pedersen, Sam Ainsworth, and Nigel Topham

amplification gadgets [30, 31] require either native code or perCPU fine-tuning, making them inapplicable in our setting. In this work, we combine PLRU cache amplification [50, 69] with nested repetition loops to overcome the interrupt-induced timing limit, achieving arbitrary amplification that is stable in production cloud environments (cf. Section 4.3).

Remote Timer

nt

R re su ea

s

1 ○

2.7

e em ur

Sta

rt

a me

4 ○

TT

M

Cache Eviction

Cache eviction is a crucial primitive to enable reliable Spectre attacks [7, 38]. Stable cache eviction enables repeated cache measurements on the same addresses and as well as to enhance the transient execution window due to longer delays loading data from memory [25, 38]. Eviction set construction relies on finding congruent memory addresses that map to the same cache set [25]. Vila [66] developed a technique to construct precise LLC eviction sets in Chrome, which was used by Spook.js to construct a Spectre attack [2]. However, for AMD CPUs, Spook.js [2] assumed a perfect LLC eviction primitive and leveraged the clflush instruction. To our knowledge finding a minimal LLC eviction-set has not been achieved by any work in the literature. Furthermore, the runtime for finding even approximately precise eviction-sets is prohibitively high for remote-timer based attacks. For example, Purnal et al. [45] constructed eviction sets with a median runtime of 25 s in local Chrome environment with a 100𝜇s timer. Schwarzl et al. [56] used a large array, greater than the size of the cache levels L1+L2, to evict data. Traversing this large array significantly slows down the attack. Thus, Roettger and Janc [61] used an eviction list to succesfully evict at least into the L2. This technique was further improved by Purnal et al. [45] by using L2 congruent eviction sets. In this work we sidestep the need for precise eviction sets by implementing the pigeonhole eviction technique, an auto-eviction technique relying on cache occupancy of L1+L2, as described by Johnson [29].

as cache activity and network contention from other tenants and processes. Figure 1 illustrates an overview of a remote side channel attack on Cloudflare Workers consisting of four steps, which is executed repeatedly on each bit of data. ○ 1 The attacker initiates a connection to a remote timer and performs a request to record a timestamp. ○ 2 The attacker leverages a JavaScript Spectre gadget to transiently access arbitrary data. Multiple gadgets may be utilized through the attack process to finally leak the targeted secret data. ○ 3 The attack uses amplification techniques to make the bit signal resilient to network and system noise. ○ 4 A second request is sent to the remote timing server to generate another timestamp. Based on the delta of the two timestamps, the attacker infers the bit value.

3

4

Threat Model and Attack Overview

We assume both the attacker and the victim execute JavaScript/WebAssembly code on distinct V8 isolates in Cloudflare Workers, assigned to the same worker process. This co-location [48, 65] assumption is reasonable due to the nature of edge computing, where the topologically nearest worker process to the request is always picked. Therefore, it is very likely that victim and attacker worker are scheduled on the same machine with no additional effort1 . We will show that forced co-location to the same process is achievable in Section 4.1. Furthermore, we assume that attacker has full control over the code running in its own isolate(s), but no native code execution. Thus, the attacker can only provide valid JavaScript and WebAssembly. Moreover, there are no existing software exploits in the JavaScript Engine, nor are there any sandbox escapes. This threat model is identical to Schwarzl et al. [56]. Attack Overview. Both the attacker and victim script are colocated within the same process and have a closely co-located remote timer. The presented attack targets the production instances of Cloudflare Workers, registered via Cloudflare’s dashboard. Therefore, all active mitigations and detections are in place. The attack’s success rate may be influenced by other users systems activity such 1 There is active data mining on the Cloudflare infrastructure on-going being able to

directly access a certain machine via a Worker [19, 20].

○ 2 Transiently access bit Attacker

Worker Secret

○ 3 Amplify signal

Process

Figure 1: High-level overview of a remote Spectre attack on Cloudflare Workers.

Attack Primitives

Here we describe our main attack primitives, which solve the above stated challenges of process co-location in Section 4.1, remote timers in Section 4.2, and robust timing-signal amplification in Section 4.3, before describing a selection of practical facilitating Spectre setup and execution gadgets in Section 4.4 to pull off a full end-to-end attack.

4.1

Bypassing Time Limits and Achieving Co-Location

Co-location of attacker and victim on the same physical host has been studied in IaaS cloud environments [48, 65], but the serverless model used in Cloudflare Workers introduces different constraints: tenants share a single process rather than a VM, and execution is bounded by per-invocation CPU time limits. Prior work [56] assumed that an attacker and victim worker can be co-located within the same process, and that the attacker can sustain execution beyond the per-invocation time limit, but left both claims unproven in production. We demonstrate both for the first time in the production system of Cloudflare Workers. Durable Objects. Durable Objects [14] are special Workers that run in only one place at any given time. Their main purpose is creating long-living and stateful applications, e.g. a chat. This allows

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

them to be used as a synchronization primitive and as message broker between multiple Workers. They are designed to stay alive indefinitely with regular invocations. Standard Workers are limited to 30 seconds of CPU time per invocation, which limits the amount of data that can be leaked per invocation, as attack setup must be repeated each time a Worker initiates. While these steps can be repeated they add a constant overhead to the attack and reduce the leakage rate. Keeping a Durable Object alive. Like a standard worker script, Durable Objects are also limited to 30 s of CPU time. However, for a Durable Object this limit is reset to 30 s each time an HTTP request is received. We can leverage this fact to significantly extend the CPU time using WebSocket messages, which are internally treated like HTTP requests. Therefore, to keep a Durable Object alive, one simply has to initiate a WebSocket connection to the Durable Object and send a message at least every 30 seconds. Since Durable Objects are still single-threaded, the Worker must regularly wait for I/O for any WebSocket messages to be received. If the thread is continuously blocked for more than 30 seconds, the Worker does not get a chance to process the incoming WebSocket message. We craft an experiment that constantly sends a keep-alive signal to the Durable Object script. We observe that the isolate can be kept alive at least for 5 h up to more than 20 h. This clearly bypasses the 30-second limit. Identifying a physical machine. Every domain being added to Cloudflare receives a custom tracing endpoint /cdn-cgi/trace. This endpoint contains various interesting data such as TLS information, the HTTP version, data centre name, a timestamp value and the fl value naming a data centre e.g. fl=114f227, whereas 114 is the id of the data centre and 227 the id of the machine. This endpoint has been leveraged for data-mining to learn about the infrastructure of Cloudflare [20]. Hitting the same process. Any memory address whose value remains stable over time can serve as a fingerprint to identify a running process or isolate. Using a Spectre gadget that can read an arbitrary 64-bit location, an attacker can probe such addresses and compare the observed values to determine whether the same isolate or process is still running. Examples of useful targets include process-wide structures or globals like the isolate root and fixedaddress mappings such as the vDSO. An attacker may first leak a candidate fixed address, then repeatedly probe that address to verify the target process. Once the attacker has identified the target process, Durable Objects can be used to force an isolate onto that process for further exploitation. C1: Limited Runtime and Co-location We use Durable Objects to keep a script running in the same isolate for hours. The /cdn-cgi/trace endpoint identifies the target machine. We then spawn Durable Objects until two isolates share one process.

4.2

Remote Timer on Cloudflare Workers

Cloudflare Workers freezes the time during raw CPU execution and only updates the timers based on IO events, e.g. performing a requests with fetch API or an update of Workers KV. Prior work [56] used subrequests as a timing proxy, treating each outbound fetch as a coarse clock tick. This approach is constrained by the Cloudflare

1 2 3 4 5

const timer = new RemoteTimer("rt.com"); timer.mark("mark S1"); event(); timer.mark("mark E1"); const delta = await timer.delta("delta S1 E1");

6

Listing 1: Interface (client) used to communicate with a remote WebSocket server.

1 2 3 4 5 6 7 8 9 10 11 12 13

async fetch() { server.addEventListener('message', (event: MessageEvent) => { const now = Date.now(); const message = JSON.parse(event.data); switch(message.type) { case 'mark': marks.set(message.name, now); break case 'delta': server.send(marks.get(message.marks[0])marks.get(message.marks[1])) } }) }

14

Listing 2: Remote Websocket timer as worker script.

Workers subrequest limit [9] and only demonstrated in a localnetwork setup, leaving its viability in the production environment unproven. We instead leverage the WebSocket API, which is not subject to the subrequest limit, to construct a high-frequency remote timer that operates entirely within the production environment. We enumerate and compare the realizations of the method below. WebSocket Remote Timer. Cloudflare Workers offers the WebSocket API to communicate with remote WebSocket servers. This interface allows it to open a WebSocket connection. Note that the communication overhead introduced by the WebSocket connection does not count towards the actual CPU time of a Worker instance. Instead, it is part of the Wall time. We verified this in the Cloudflare dashboard, as it reflects statistics about the CPU and Wall time. In contrast to the amount of subrequests, Cloudflare Workers does not restrict the amount of messages being transmitted in WebSocket connections. For many subsequent WebSocket calls the CPU time barely increased. Thus, for the paid version with an offered runtime of 30 s per Worker invocation, the Wall time can be several minutes of execution time. Our WebSocket communication uses one call to mark a timestamp. To receive the delta, another command is used to compute the difference between two marked timestamps. Listing 1 illustrates the usage of the remote timer and how to trace an event. This approach can also be optimized by collecting the timestamps for a certain event on the server first and then gathering the list of results directly from the server. Co-Located Worker as Timer As Date.now is updated on I/O operations, we analyze and exploit the available API calls that can trigger timer updates. The returned resolution of Date.now is still

Martin Schwarzl, Haocheng Xiao, Albert Pedersen, Sam Ainsworth, and Nigel Topham

in the millisecond range2 . We leverage scheduler.wait, to trigger a short-lived I/O operation. Date.now then updates its value even though the I/O operation is short. Using the interface described in Listing 1, we spawn another Worker script that acts as a WebSocket server, which calls Date.now for each mark command and provides the delta between two timestamps (WS+Date.now). Listing 2 illustrates a worker script acting as remote WebSocket timer. External WebSocket Server as Timer. To reduce latency, Cloudflare Workers routes requests to the topologically closest data center. We host a dedicated WebSocket server on an AWS EC2 instance in eu-north-1 (Stockholm), approximately 1200 km from the Workers data center (WS+AWS). This server uses the rdtsc instruction for high-resolution timestamps and is built with the uWebSocket C++ library3 with TCP_NODELAY and TCP_QUICKACK enabled. We deliberately chose this distance to demonstrate that a practical timer remains achievable even over a wide-area connection. Co-Located Durable Object as Timer. As discussed in Section 4.1, Durable Objects co-locate two isolates in the same process. The specific process does not matter. The attacker invokes the victim’s script through an HTTP request. This request places the victim in the attacker’s process. At the time of writing, Cloudflare runs a single workerd process per machine. Therefore, the attacker only needs to co-locate two isolates on one machine. The attacker reads the current machine identifier from the /cdn-cgi/trace endpoint. The attacker spawns new Durable Objects, where each one starts a new isolate. The attacker repeats this until two isolates share the same process. Following the birthday paradox [18], this search completes in about one second. The co-located Durable Object then serves Date.now timestamps over a WebSocket (WS+DO). Cloudflare Sandbox as Timer. The Cloudflare Sandbox SDK [12] runs an arbitrary containerized process directly on Cloudflare infrastructure. Cloudflare offers it on paid Workers plans. Each Sandbox requires a Durable Object that hosts the container on the same machine. Co-locating the Sandbox therefore reduces to the Durable Object co-location of Section 4.1. The container runs native code and serves rdtsc timestamps over a WebSocket (WS+Sbx). This timer removes the off-platform network hop. Timer Resolution. To measure the effective resolution of our remote timers, we conduct the following experiment. We use an internal binding to generate controlled timing delays. Only the Cloudflare Workers team can assign this binding. It provides a highresolution timer. Our experiment compares five remote timers, each connected through a WebSocket. We measure their resolution for delays from 10 µs to 2 ms. The WS+Date.now timer returns Date.now. The WS+PerfNow timer returns the internal highresolution timer value. Attackers cannot assign this binding, so we include WS+PerfNow only as the reference upper bound for a co-located remote timer. The WS+AWS timer runs on an AWS instance approximately 1200 km from the Worker. The WS+DO timer runs inside a co-located Durable Object. It uses Date.now, as a Durable Object exposes no high-resolution clock. The WS+Sbx timer runs inside the co-located Sandbox introduced above. Using the internal high-resolution timer, we separately measure the ground truth of each delay. 2 https://developers.cloudflare.com/workers/runtime-apis/performance/ 3 https://github.com/uNetworking/uWebSockets/

Within the same Worker invocation, we perform 250 measurements per remote timer. We repeat the entire experiment 20 times. In total, we collect 5000 samples per remote timer. We compute the median and the standard deviation over all samples per delay. We observe variances on the order of several hundred microseconds across the timers. Table 1 summarizes the median values for all timer types. The WS+Date.now timer reaches an effective resolution of roughly 1 ms. The co-located WS+DO timer reaches the same 1 ms resolution. A Durable Object exposes only Date.now, so colocation alone does not improve the resolution. The WS+PerfNow, WS+AWS, and WS+Sbx timers reach sub-millisecond median resolution. WS+PerfNow is not attacker-deployable, and WS+AWS pays a wide-area network hop. Only WS+Sbx combines sub-millisecond resolution, co-location, and attacker deployability. This motivates the native rdtsc timer inside the co-located Sandbox instead of a Durable Object. The median resolution alone does not determine whether a timer is usable in practice. All remote timers are subject to system workload. Their standard deviations range from several hundred microseconds up to a few milliseconds and depend on the current system utilization (Figure 10). The WS+Sbx timer reaches the lowest median error. No remote timer therefore resolves an individual sub-millisecond delay reliably. We address this variance through signal amplification (Section 4.3). We amplify the difference between a cache hit and a cache miss up to the millisecond scale, where it exceeds the timer standard deviation. At this scale, all five remote timers separate cache hits from cache misses reliably. We further evaluate the effectiveness of our remote timers in Section 5, where we observe that for a sufficiently large signal, 5 to 40 samples are sufficient to differentiate between a leaked ’0’ and ’1’ bit. Timer

0.01

0.05

Target delay [ms] 0.10 0.25 0.5

1.0

2.0

0.000 0.071 0.032 0.000 0.031 0.010

0.000 0.112 0.074 0.000 0.057 0.050

0.000 0.162 0.132 0.000 0.116 0.100

0.000 0.313 0.281 0.000 0.292 0.250

1.000 0.586 0.568 1.000 0.573 0.500

1.000 1.096 1.091 1.000 1.100 1.000

2.000 2.101 2.122 2.000 2.125 2.001

Standard deviation 𝜎 [ms] WS+Date.now 0.320 0.332 WS+PerfNow 0.079 0.079 WS+AWS 0.137 0.145 WS+DO 0.000 0.196 WS+Sbx 0.163 0.109 Local 0.038 0.023

0.449 0.064 0.168 0.300 0.133 0.014

0.490 0.702 0.174 0.455 0.187 0.013

0.503 0.241 0.317 0.499 0.231 0.018

0.334 0.262 0.446 0.481 0.259 0.007

0.743 0.518 0.675 0.472 0.319 0.010

WS+Date.now WS+PerfNow WS+AWS WS+DO WS+Sbx Local

Table 1: Median timing and std-dev for the evaluated timers (in milliseconds), measured against controlled target delays from 10 µs to 2 ms. Each cell aggregates 5000 samples.

Resolution of amplified delta. To further measure the stability of the timers, we conduct an experiment that creates a 400 µs delay between an amplified cache hit and miss using the PLRU gadget from leaky.page [50]. We plot the timing distributions as kernel-density estimates. As shown in Figure 2, the two distributions are visually distinguishable even from 50 randomly drawn measurements, confirming that the timing signal is strong enough to classify cache hits and misses by eye. These results are consistent with remote timing results in similar settings [27, 57, 58].

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

Density

1 0.5 0

0

1

2

3

4

Density

Network Timer [ms]

4 2 0

0.6

0.8

1

1.2

1.4

1.6

1.8

2

2.2

Ground Truth [ms]

Figure 2: Kernel-density estimate of 50 amplified cache-hit (solid) and cache-miss (dashed) timing measurements. Top: network timer showing overlap due to jitter. Bottom: ground truth with cleaner separation. Vertical lines mark respective medians. C2: Remote Timer. Despite Cloudflare Workers freezing timers during CPU execution, our co-located Sandbox timer (WS+Sbx) achieves sub-millisecond median resolution (Table 1). Individual measurements exhibit standard deviations of 0.5 ms to a few milliseconds under production noise. Amplifying the signal to the millisecond scale (Section 4.3) makes all five timers sufficient to distinguish cache hits from misses.

4.3

Signal Amplification

A challenge for remote Spectre attacks is bridging the gap between the nanosecond-scale timing differences produced by cache side channels and the millisecond-scale resolution of remote timers. Prior work [56] relied on pure repetition, executing the Spectre gadget hundreds of thousands of times to accumulate a measurable signal. This achieved leakage of only 120 bit/h, as the majority of run-time was consumed by repeated gadget setup rather than actual signal accumulation. PLRU-based amplification [50] improves upon this by exploiting the widely deployed pseudo-last-recently-used L1D cache replacement policy to generate many cache misses from a single leaked bit, achieving higher amplification rates without repeated leakage triggers. However, PLRU amplification alone is limited to approximately 400 µs of timing difference before system interrupts and context switches destroy the cache state. A 400 µs difference is sufficient under low timer noise. Under production noise, however, the remote-timer standard deviation reaches up to a few milliseconds (Table 1) and can exceed this difference. This motivates a further amplification step, cf. Figure 3. More powerful amplification approaches from the literature are not directly applicable in our setting. Showtime [45] and Hacky Racers [69] rely on performance counter access or fine-grained ILP contention control that is unavailable inside the Cloudflare Workers JavaScript sandbox. Gates of Time [31] requires a co-resident attacker process capable of manipulating contention across hardware

threads, which the serverless model does not permit. We therefore choose and extend PLRU-based amplification as it relies solely on the L1D cache replacement policy, which is uniformly implemented on all AMD EPYC CPUs deployed by Cloudflare Workers, and requires no privileged access or cross-process coordination. Nested-Loop Amplification. We overcome the 400 µs interruptinduced ceiling of standalone PLRU amplification by combining it with an outer repetition loop, creating a nested-loop structure that achieves arbitrary amplification independent of interrupt frequency. Figure 3 illustrates the approach: rather than attempting to amplify a single transient execution indefinitely, we repeat the full sequence of setup, transient leak, and PLRU amplification across many iterations. Each iteration independently encodes the leaked bit into cache state and amplifies it. If an interrupt destroys the L1 state during one iteration, the subsequent iteration re-establishes the state and continues accumulating timing difference. Listing 3 shows the nested-loop structure. The inner loop (INNER_REP) controls the PLRU amplification within a single iteration, while the outer loop (OUTER_REP_NUM) repeats the full gadget execution. A remote timer measurement brackets each outer-loop block, and we take the median over multiple samples (SAMPLE_NUM) for robustness. The total accumulated timing scales linearly with the number of inner-loop repetitions. The amplification factor is therefore a freely tunable parameter, cf. Figure 9 in Appendix A. This approach has two key properties. First, the timing difference is unbounded. By increasing the number of outer-loop iterations, we can produce arbitrarily large timing differences that exceed any practical remote timer resolution. Second, the approach is resilient to noise. If an interrupt destroys L1-cache state mid-iteration, the PLRU oscillation loop produces only hits for both 0 and 1 cases, so the disrupted iteration adds equal time to both paths so does not corrupt accumulated signal. PLRU Oscillation Gadget. The PLRU amplification is implemented in WebAssembly to avoid JIT-induced nondeterminism in the oscillation loop. Each invocation proceeds in three phases. First, a clearSet phase loads eight cache-line-aligned addresses congruent to the target cache set, evicting all prior occupants. Second, a prime phase loads seven eviction entries plus a keepAlive entry, fully occupying the 8-way set in a defined PLRU tree state. Third, the oscillation loop accesses all seven eviction entries interleaved with repeated accesses to keepAlive. Because keepAlive is touched after every entry, it consistently holds the most-recently-used position and is never evicted. Whether the secret-dependent cache line displaced one of the seven entries during the transient execution determines whether those entries hit or miss during oscillation, producing the timing asymmetry that encodes the leaked bit. Our approach uses the oscillateTreePLRU2 [50] that accesses the keepAlive after every entry. The increase in keepAlive frequency makes the PLRU tree state resilient to incidental cache accesses from JIT-compiled code and OS interrupts, which are more frequent in the Cloudflare Workers execution environment than in a local browser. The resulting reduction in absolute timing delta per iteration is compensated by the outer repetition loop in our nested-loop amplification (Section 4.3). Timer Calibration. Before leaking secrets, we calibrate the timing threshold dynamically for each worker invocation. We leak multiple known 0 and 1 bits and verify that the resulting timing distributions are well separated. The classification threshold is set as the midpoint between the median timing

Martin Schwarzl, Haocheng Xiao, Albert Pedersen, Sam Ainsworth, and Nigel Topham Leak Bit 0

Leak Bit 1

Setup

Setup

L1 Hit

L1 Hit

L1 Hit L1 Hit L1 Hit

.. .

L1 Miss L1 Hit L1 Miss

Interrupt L1 Hit L1 Hit L1 Hit

.. .

.. . Interrupt L1 Hit L1 Hit L1 Hit

.. . Time

Figure 3: Timing-difference accumulation for leaking bit 0 vs. bit 1. The setup stage prepares the PLRU cache state and encodes the transiently accessed secret. Before an interrupt, PLRU accumulates timing difference through cache hit/miss asymmetry. If an interrupt destroys cache state, the PLRU gadget stops accumulating. With nested repetition (red dashed line), each iteration re-establishes the state to continue accumulating.

1 2 3 4 5 6 7 8 9 10 11

for (let s = 0; s < SAMPLE_NUM; s++) { timer.mark("mark S"+s); for (let r = 0; r < OUTER_REP_NUM; r++) { setup(); // branch mistrain, cache control leak(secret_bit); // transient read PLRU(cacheset, INNER_REP); // amplify } timer.mark("mark E"+s); } delta_t = fetchFromServer(SAMPLE_NUM); return median(delta_t);

Listing 3: Nested-loop PLRU amplification with remote timer. values for 0 and 1 bits. This per-invocation calibration accounts for varying runtime conditions across different requests. C3.1: Robustness (Signal Amplification). Existing amplification techniques do not transfer to our setting. PLRU amplification alone is limited by interrupt frequency and pure repetition is infeasible for practical attacks. Our nested-loop approach combines both to achieve arbitrary, interrupt-resilient amplification compatible with remote timers.

4.4

Spectre Gadgets

The nested-loop amplification of Section 4.3 wraps the setup and leak calls of a Spectre gadget. We now describe the gadgets that realize this transient read. Following prior work [2, 56], our attack chain requires two types of Spectre gadgets: a heap-address gadget

that leaks address information from objects allocated in proximity to attacker-controlled objects, and a secret-leakage gadget that reads from arbitrary 64-bit addresses. The heap-address gadget provides the address anchor required to bootstrap the secret-leakage gadget, which then extracts data from victim workers’ address space. We enhance prior heap-address gadgets [2, 56] to eliminate the fragile cacheline-alignment requirement, and integrate pigeonhole-style eviction [29] to remove explicit eviction-set construction entirely. We also simplify prior secret-leakage gadgets [2, 56] by eliminating the fake-pointer setup stage, by utilizing allocator object co-location and details of V8 Uint8Array backing buffers. Heap-Address Gadget. The heap-address gadget leaks address information from V8 heap objects allocated near attacker-controlled objects. This information serves as the address anchor for the subsequent secret-leakage gadget. Prior heap-address gadgets [2, 56] rely on a speculative out-ofbounds access that requires specific cacheline-level alignment: the length field and the buffer pointer of a TypedArray must be split across two cache lines so that one can be evicted without the other. Finding this alignment requires allocating objects across approximately 2 MiB of heap space and is brittle across V8 versions and allocator changes. Additionally, these gadgets require explicit eviction-set construction before each invocation: in our measurements, finding a working eviction set requires between 1 and 50 attempts and takes approximately 15 s, with a resulting 50 % per-gadget failure rate that significantly reduces end-to-end leakage throughput. We replace the alignment-sensitive out-of-bounds approach with a speculative type-confusion [37] gadget. Under speculative execution, the gadget accesses a Uint8Array object as if it were a Uint32Array, reading 4 bytes per access instead of 1. This mismatch allows the transient path to read past the intended boundary and access adjacent heap metadata, including compressed pointers that reveal address information. The key advantage is that we separate the speculated branch value (the map pointer) from the leakage-critical data fields. The map pointer, which must be evicted to trigger misspeculation, resides at the beginning of the object, while the data to be leaked is located several cache lines away. This separation eliminates the strict split-line alignment requirement. Figure 4 illustrates the memory layout for our heap-address gadget. Pigeonhole Eviction. To avoid explicit eviction-set construction, we adapt the pigeonhole-eviction technique proposed by Johnson [29]. In V8, every JavaScript object stores a map pointer as its first field, a hidden-class descriptor that JIT-compiled type checks read to verify the object’s type. This map pointer must be evicted to stall branch resolution and open a speculation window. Rather than constructing an eviction set to flush this value before each gadget invocation, we allocate a large pool of attacker objects and select a random pair per invocation. With a pool of 500 000 objects, the attacker-object pairs alone span over 40 MiB of V8 heap metadata, far exceeding any LLC. Any randomly selected pair is therefore guaranteed to be an LLC miss. The pigeonhole principle ensures this when the working set exceeds the cache capacity. The gadget requires an asymmetric cache state: the map pointer must be evicted, while the data fields of the adjacent fakeUint32Array, the target of the transient read, must reside in cache for the transient read to complete before the window closes. Pigeonhole eviction guarantees the former without any explicit flush or eviction-set

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

Obj I (TypedArray) 2

1

Obj P

mapB

cacheline K

length = N

... Uint32Array Pointer

Base Pointer

TypedArray[i] [1] ...

cacheline K+1

3

prototypeB

...

1

Uint8Array Pointer

Aligned

Externel Pointer

TypedArray[i] [0]

...

AttackerObjB

prototypep

prototypeI ... ... ...

AttackerObjA

mapp

mapI

Not Aligned

Uint32Array

Uint8Array

mapUint32Array

mapUint8Array

...

2

3

...

...

Uint32Array element length = N

Uint8Array element length = N

...

...

Externel Pointer

TypedArray[i] [N-1]

Externel Pointer

Base Pointer

Base Pointer

Secret

Uint32[0] 4

...

JITed speculative access

Uint32[N-1] Secret

V8 managed pointers

Uint32Array Backing Buffer

Secret

Uint8Array Backing Buffer

...

Uint8[0] ... Uint8[N-1] Secret ... Secret

Figure 4: Memory layout for our heap-address gadget. The speculative type confusion between Uint8Array and Uint32Array allows reading past the intended boundary to leak adjacent address information.

traversal. We prefetch the data fields of the selected pair three times prior to each gadget call to ensure the latter. Residual incidental map pointer cache hits may occasionally occur, but our nested-loop amplification (Section 4.3) amortizes this. A single failed iteration contributes zero signal rather than corrupting the accumulated result. Object Pool Allocation. We allocate between 500 000 and 3 000 000 object triplets, each consisting of two attacker objects and one indirection wrapper. The two attacker objects together are sized to match the training type (188 bytes), ensuring the transient out-ofbounds read lands at the correct offset within the adjacent victim object. The indirection wrapper holds a reference to the victim typed array, causing V8’s garbage collector to promote it adjacent to the speculatively accessed fake typed array in the old-generation heap. At this scale, triggering garbage collection after each triplet, the conventional promotion approach [2, 56], would exceed the 30 s initialization limit. We observe that V8’s mark-and-sweep collector traverses the object graph breadth-first. Referencing alternating attacker and victim objects from a single root array ensures both types are promoted contiguously to the old generation in a single collection pass. We additionally allocate a warm-up pool of 2000 objects prior to the main allocation to fill heap fragmentation gaps and improve physical adjacency. In over 99 % (𝑛 = 10000) of cases,

attacker and victim objects are physically adjacent after promotion. To avoid non-deterministic RNG latency in the timed section, all random selection indices are pre-computed before the outer measurement loop begins. Memory Layout Search. After pool allocation, the attacker validates the heap layout before leaking. The attacker iterates over L1 cache set offsets and measures the PLRU timing signal for a known bit-0 and bit-1 value across 30 samples per offset. An offset is accepted if the hit and miss timing distributions are well separated, confirming physical adjacency of attacker and victim objects and a usable PLRU signal. If no offset yields a clean signal after 10 attempts, the invocation is aborted. Secret-Leakage Gadget. The secret-leakage gadget reads data from arbitrary 64-bit addresses within the shared address space, enabling cross-worker data extraction. Prior secret-leakage gadgets [2, 56] require first leaking a heap address via the heap-address gadget, then fabricating a fake pointer value to drive the transient dereference path (Figure 5, middle). This dependency chain adds setup latency and increases cumulative error propagation. We allocate 500 000 pairs of AttackerObject and Uint8Array using the same pigeonhole pool. Prior to each gadget invocation, we write a fake Uint8Array layout directly into the backing buffer of the selected Uint8Array: a length field at byte offset 32 and the 64-bit target address as the base pointer at byte offset 40. Under type confusion, the transient path reads the selected AttackerObject as an ObjP. The ptr field in ObjP’s layout resolves to the adjacent Uint8Array’s backing buffer, where the fake header resides. The transient path follows the embedded base pointer, the 64-bit target address, and reads 4 bytes from that location. Extracting individual bits and encoding them into probe array cache set accesses enables single-bit leakage per invocation. Note that the Uint8Array backing buffer must not exceed 0x40 bytes, since V8 allocates larger Uint8Array backing buffers in a separate heap region, which breaks the layout assumption. The attacker applies the same memory layout search as in Section 4.4, retrying up to 5×. Figure 5 illustrates the memory layout, and Listing 4 sketches the corresponding training and leakage code. The branch in spectreGadget is mistrained on ObjP instances so that, when invoked on the adjacent Uint8Array-backed object, the JIT speculatively follows the obj.ptr[0] dereference and emits the encoded cache access consumed by our PLRU amplifier (Section 4.3). On the AMD EPYC CPUs deployed in Cloudflare Workers, training only the local branch is insufficient: TAGE-style predictors [59] index on long global history, so we additionally invoke wasm_plru during training to match the global branch context observed during leakage (20 local-history and 5 global-history training rounds per leakage call). Compared to prior variants that require constructing a fake TypedArray at a pre-leaked heap address [2], our design removes a dependency stage entirely: the target address is injected directly into the adjacent Uint8Array backing buffer, requiring no prior address leak to bootstrap. The secret-leakage gadget can be replaced with any other 64-bit Spectre gadget [2, 7, 34, 38, 39, 41, 42, 68] that produces a transient read of an attacker-controlled address. Speculative-Window Enlargement. A successful exfiltration requires that both the dereference of obj.ptr and the subsequent load from the embedded 64-bit address complete before the misprediction is resolved. We extend the transient window in two ways.

Martin Schwarzl, Haocheng Xiao, Albert Pedersen, Sam Ainsworth, and Nigel Topham

1

Object P

Object I

AttackerObj

mapp

mapI

mapObj

prototypep

prototypeI

a0

b0

... ... ...

... ... ...

an

bn

... ...

TypedArray Pointer

Fake Pointer

base pointer

1 2

prototypeObj TypedArray_ptr

3

...

4

TypedArray

5

mapTypedArray

6 7 8 9

valid_data_ptr

10 11

64b data_ptr

12

...

...

...

13

length

fake length

...

...

external pointer (8B)

secret_addr (8B)

base pointer

0x0

4

Array Backing Buffer

JITed sepculative fixed offset access

fake length ... secret_addr (8B)

Typedrray Backing Buffer

random data

TypedArray Backing Buffer

3

...

64b data_ptr

2

mapTypedArray

14 15 16 17

spectreGadget() { if (obj instanceof ObjP) { leak(obj.ptr[0]); } } wasm_plru() { // step 1: setup cache for PLRU // step 2: call spectreGadget // step 3: PLRU amplification } // Training: mistrain branch predictor for (let j = 0; j < 20; j++) { spectreGadget(); // local history } for (let j = 0; j < 5; j++) { wasm_plru(); // global history } // Leaking wasm_plru();

0x0

Listing 4: Speculative type confusion training and leaking. Secret

JITed speculative pointer access

Secret

v8 managed pointers

attacker controlled pointers

Figure 5: Memory layout for the secret-leakage gadget via speculative type confusion. Left: training object P. Middle: prior approach [56] requiring a pre-leaked fake pointer. Right: our approach, writing a crafted fake Uint8Array header into the adjacent backing buffer. Co-locating AttackerObj and TypedArray makes V8 create the equivalent base pointer itself, which removes the fake-pointer setup stage.

First, the instanceof check in spectreGadget is preceded by a sequence of long-latency arithmetic operations on a value derived from the map pointer, so that branch resolution stalls until that chain retires. Second, prior to entering the gadget we issue several dependent integer divisions whose result feeds the branch condition. These divisions occupy the AMD scheduler’s execution ports for tens of cycles. They widen the speculation window enough for the two-level pointer chase to retire its cache effects. We empirically tune the number of arithmetic operations per call, typically 4 to 8, until the encoded cache access becomes observable through the PLRU amplifier. Lower counts collapse the window and the leakage drops to noise. Excessive counts only reduce throughput without improving accuracy. Encoding and Decoding. For each leaked bit, the gadget masks out a single bit from the transiently read 4-byte value and uses it to select between two disjoint cache sets in the probe array. The PLRU amplifier (Section 4.3) then accumulates the timing asymmetry between these two sets into a remote-timer-observable difference. The attacker reconstructs a full 64-bit address bitwise across 32 invocations of the heap-address gadget followed by 32 invocations of the secret-leakage gadget. Each per-bit decision uses the threshold calibrated as described in Section 4.3.

C3.2: Robustness. Pigeonhole eviction replaces explicit evictionset construction with random selection from a large object pool, eliminating the per-invocation setup cost and its 50 % failure rate. The heap-address gadget removes the cacheline-alignment requirement via speculative type confusion, and our secret-leakage gadget removes the fake-pointer dependency.

5

Evaluation

In this section, we demonstrate the practicality of our presented attack primitives in the production environment of Cloudflare Workers. Our attack significantly outperforms the reported maximum leakage rate of 120 bit/h [56] with a leakage rate of up to 12 bit/s (43 200 bit/h). Setup. We run all our experiments with the (WS+Sbx) timer, colocated on the same machine. The target systems were running on Linux servers equipped with AMD EPYC CPUs (Zen2 and Zen3). Cloudflare Workers operates a highly homogeneous server fleet, with successive generations uniformly deploying AMD EPYC processors [8, 10, 11]. This hardware uniformity benefits the attacker, as microarchitectural assumptions such as cache-replacement policies and scheduler behavior remain consistent across machines. Consequently, an attack gadget calibrated on one machine is likely to behave identically on another, removing the need for per-machine parameter tuning. Note that the following experiments running on the production system are intentionally targeting memory regions owned by a crafted victim isolate to not accidentally leak customers data. To get comparable results, we pin our measurements for both attacker and victim scripts to a specific machine. We run the experiments at night on the machine, with a CPU utilization between 10 and 25 percent to observe the best possible results. Memory Layout. To indicate the strong variance on the production system, we performed a first experiment on the success rate of identifying a stable memory layout. We measure how often a stable memory layout ready for one of our gadgets succeeds. We run this experiment for a period of roughly three days. Figure 6 illustrates the success rate of the experiment and the dashed line illustrates the CPU utilization on that specific machine during that

Rate

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

Success Rate

1 0.8 0.6 0.4 0.2 00:00

12:00

CPU Utilization

00:00

12:00

00:00

Time (HH:MM)

Figure 6: Success rate of initial memory layout step on a production system using a remote timer. We consider the stage to be successful if a run starts leaking memory.

Figure 7: Leakage of vDSO data from production system with no bit errors.

time period. The stage is considered successful if it successfully enters the next stage of leaking the compressed pointer. There is a direct correlation between the success rate of our experiment and the systems CPU utilization. The system utilization thus influences the success rate of each of our presented experiments. An attacker can maximize leakage rate by targeting off-peak hours, though slower attacks remain feasible at any time of day even under high load. Timer Stability. We collect 253 ground-truth sessions over 28 hours on the production system. The per-session miss−hit difference stays strictly positive, with a median of 1.17 ms (𝑛 = 253, 𝜎 𝜇 = 4.75%). We conclude that hit/miss distinguishability is preserved across time. The absolute throughput follows a load-dependent diurnal pattern, cf. Appendix B. Classifying a bit. We classify leaked bits in remote Spectre attacks by first building an empirical baseline from 100 architecturally reachable, known values to capture the distributions of measured “0” and “1” responses. From that baseline, we determine a classification threshold as the 35th percentile of the one-bit timing distribution, which empirically produced the most robust separation. For each leaked bit we then perform a two-sided hypothesis test using that threshold. We count how many measured samples fall above the threshold when testing for a one and how many fall above it when testing for a zero, and the majority determines the inferred bit. Aggregating these per-bit decisions across a byte yields the byte classification. Bypassing DyPrIs with Durable Objects. DyPrIs enforces process isolation after a script execution finished. This means, that as long as the Durable Object is kept alive it can leak without being interrupted. Due to the long-living nature of Durable Objects, not process isolating is a major implementation flaw when trying to detect on-going attacks. Moreover, DyPrIs relies on normalizing the amount of branch accesses by the amount of iTLB accesses. As our WebSocket-based remote timer is frequently called, the amount of code being used between a sample is increased, thereby lowering the ratio between an event normalized by iTLB accesses. Leaking the isolate root. V8 uses pointer compression to reduce memory consumption and improve cache locality. In V8, all heap objects reside in a 4 GiB region called the isolate heap, allowing 64-bit pointers to be represented as 32-bit signed offsets from a base pointer, the upper half of virtual address, referred to as the isolate root [60]. This technique is used extensively for object properties, internal fields, and array element pointers.

We design a worker that uses the speculative type confusion gadget described in Section 4.4 to leak the isolate root. The speculative type confusion gadget leverages a type confusion between a Uint8Array into a Uint32Array. The gadget reads 4 bytes with one memory access at the given index and masks out the bit to be leaked. To verify if our leaked isolate root is correct, we place known random values next to our target pointer, which we leak in addition. In addition, leveraging an internal binding, we can verify whether our leaked address is correct. We repeat the attack 1000 times. A single run is considered successful if we correctly leak the isolate root. We configure the attack to run with a window size of 5 , 8500 inner loops and 25 outer loops, achieving a leakage rate of 12 bit/s (𝑛 = 100, 𝜎 𝜇 = 16.75%) with an average accuracy of 99.60 %. Memory Layout. We leak the full isolate address over 10 consecutive redeployments. We observe a linear allocation of isolate roots with a 2 GiB offset. Moreover, the bump allocator in V8 keeps object offsets stable across executions of the same script. We conclude that both properties ease the search for valuable addresses, cf. Appendix C. Leaking from the vDSO. To test leaking from a 64-bit address, Cloudflare Workers team added an experimental internal debug binding for our experiments that returns the address of the vDSO section. We design a worker that uses the gadget to leak arbitrary data. Our attack leaks 128 B from the vDSO. We start at offset 0xe20, where the string gettimeofday is located. Our parameterization on the production system is a window size of 10, 8500 inner loops and 25 outer loops. With this configuration and the WS+Sbx timer, we achieve a leakage rate of up to 12 bit/s (𝑛 = 100, 𝜎 𝜇 = 30.14%) with an average accuracy of 99.16 %. Figure 7 displays the leaked bytes of our attack with perfect results. Leaking from another Worker. We demonstrate the full end-toend attack by leaking a JWT token placed in a co-located victim worker. The attack chain proceeds as follows. First, the attacker uses the heap-address gadget to leak its own isolate root. Next, the attacker uses the secret-leakage gadget to follow internal pointer chains relative to that root. This enables traversal into the shared process address space and eventual access to the victim worker’s heap. We target a JWT token stored in the victim’s memory and leak it byte by byte. Figure 8 illustrates the bitwise classification for the first byte of the leaked token. The measured bit-classification accuracy and leakage rate are in line with the vDSO experiment, as the same gadgets and amplification parameters are used.

Martin Schwarzl, Haocheng Xiao, Albert Pedersen, Sam Ainsworth, and Nigel Topham

Test for 0 Test for 1 threshold Leaked bit=0 Test for 0 Test for 1 threshold Leaked bit=1 Test for 0 Test for 1 threshold Leaked bit=1

Test for 0 Test for 1 threshold

Leaked bit=0 Test for 0 Test for 1 threshold Leaked bit=0 Test for 0 Test for 1 threshold Leaked bit=1

Test for 0 Test for 1 threshold

Leaked bit=0 Test for 0 Test for 1 threshold Leaked bit=1

Figure 8: Bitwise classification results for the first byte (the letter ‘e’, 0b01100101) of the leaked JWT token. Each subplot shows the separation between ‘0’ and ‘1’ tests for a single bit.

6

Mitigations

DyPrIs [56] monitors performance counters per worker script, normalizes them by iTLB accesses, and process-isolates scripts that exceed a detection threshold. The deployment in Cloudflare Workers reveals two implementation flaws that our attack exploits. First, isolation is enforced only after a script execution completes. Since Durable Objects never complete their invocation while keep-alive signals are received, the attacker leaks data throughout a single uninterrupted execution and is never isolated. Second, the normalization metric is not robust to I/O-heavy code paths. WebSocket timer calls introduce substantial iTLB activity independent of the Spectre gadget, suppressing the normalized ratio below the detection threshold. We conclude that both flaws are fundamental limitations of the detection approach rather than implementation oversights. An attacker with control over the I/O pattern can always inflate iTLB activity to evade normalization-based detection. A robust detection requires real-time monitoring during execution

rather than post-hoc isolation, and a metric invariant to the monitored script’s I/O workload. The detection signals could be extended by focusing on the exfiltration stage i.e., timing information. V8 Sandbox. The basic idea of the new V8 sandbox is to eliminate remaining raw (64-bit) pointers [23]. This would reduce the attack surface, in case an attacker has an arbitrary read and write primitive within the sandbox, by restricting it to only the heap. Thus, an attacker cannot corrupt memory outside of the pointer “cage”. Heap pointers become 32-bit offsets into a 4 GiB pointer cage. Buffer pointers, such as TypedArray backing stores, become 33-bit offsets that address the full 8 GiB sandbox [15]. Cloudflare Workers has deployed the sandbox by introducing per-isolate sandbox groups into V8 [15]. We can confirm that the presented gadget is mitigated if the V8 sandbox is enabled by testing locally. The type confusion used in the attack is not possible anymore, as there is no raw 64-bit pointer used. However, there are many other objects that are not yet ported to the V8 sandbox, and could be leveraged for crafting gadgets. Moreover, other Spectre variants might still be exploitable, given the vast amount of potential for crafting Spectre gadgets. We conclude that the V8 sandbox hardens the crafting of simple 64-bit speculative type confusions, however, it does not remove the potential of Spectre gadgets. In-Process Isolation. Google previously gave up on in-process Spectre defense, and implemented full process isolation for each origin in Chrome [42, 47]. Still, inprocess isolation at scale, could play a crucial part in protecting the tenants from in-process Spectre. Kiriansky [36] demonstrated that hardware-assisted memory protection mechanisms like Intel MPK can mitigate Spectre attacks. Various MPK-based schemes were proposed to provide efficient in-process isolation [5, 26, 51, 52]. The major drawback of MPK is the limited number of protection domains, with up to 15 keys available per process. VDom [70] overcomes the security domain implementation by leveraging address-space identifiers (ASIDs). Unterguggenberger et al. [62] presented an approach leveraging Intel-TME for in process isolation supporting up to 32K tenants per process. While these approaches look promising the overhead for a strongly multithreaded environment such as Cloudflare Workers is unclear. Cloudflare Workers deployed MPKbased in-process isolation as a coordinated mitigation [15]. Modern x64 CPUs expose up to 15 protection keys. V8 reserves a few keys for its JIT compilers, leaving approximately 12 keys for isolation. Cloudflare Workers assigns a protection key to each isolate heap. A cross-isolate access traps in hardware unless the accessing thread holds the matching key. For our attack, the transient read of the secret-leakage gadget now targets a differently-keyed heap region and faults unless the attacker isolate shares the victim key. With random key assignment, this traps approximately 92 % of cross-isolate accesses, corresponding to 11 out of 12 keys. To reach complete coverage, Cloudflare Workers combines the keys with the V8 sandbox and places each sandbox under a strictly rotating key. No sandbox within a 32 GiB window shares a key, so neighboring sandboxes act as each other’s guard regions. The residual risk is an attacker who controls the PKRU register, requiring arbitrary code execution [17]. Our attack demonstrates the necessity of hardware-enforced isolation such as MPK. The software-only countermeasures of Cloudflare Workers, restricted timers and performance-counter detection, prove insufficient against state-of-the-art amplification and evasion techniques. We conclude that hardware-assisted protection is the

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

most effective mitigation against in-process Spectre attacks in a shared-process environment. Secrets Proxy. LeakLess [49] introduces an innovative approach to protecting secrets in Function-as-a-Service (FaaS) environments. The primary goal of LeakLess is to store secrets outside the languagelevel isolated process, instead placing them in a separate I/O module. This module can either run in a distinct process or on an entirely different machine. To enable this, secrets must be annotated. The module then decrypts and inserts them into requests as needed, for instance when a subrequest requires a bearer token. While this approach offers enhanced protection for secrets in Cloudflare Workers, it requires manual annotation by developers to flag secrets. Moreover, the scalability of this approach for Cloudflare Workers is unclear. The entire request object may contain sensitive information, and certain operations may process these secrets directly within the worker.

7

Conclusion

In this paper, we reconsidered the security of Cloudflare Workers with respect to remote Spectre attacks. We explored the attackers’ possibilities to co-locate remote timers in Cloudflare Workers. Our timers achieve a median accuracy in the tens of microseconds (𝜎 0.5 ms to a few milliseconds) under production load. There is no way of mitigating a remote timer if an attacker is allowed to connect to remote hosts. In combination with two speculative type confusion gadgets, we mounted a remote Spectre attack in the production system of Cloudflare Workers, leaking a JWT token from a co-located victim worker at up to 12 bit/s (𝑛 = 100, 𝜎 𝜇 = 30.14%) with an accuracy of 99.16 %, outperforming the previous attack by a factor of 360×. The Cloudflare Workers team found no indicators of the vulnerability being actively exploited. Cloudflare Workers mitigated the attack in a coordinated effort by integrating the V8 Sandbox limiting transient access to 64-bit pointers, improving the detection capabilities of DyPrIs, and deploying MPKbased in-process isolation.Our attack demonstrates the necessity of hardware-enforced isolation, as the software-only countermeasures of Cloudflare Workers proved insufficient against state-of-the-art amplification and evasion techniques.

References [1] Onur Acıiçmez, Werner Schindler, and Cetin K. Koc. 2006. Cache Based Remote Timing Attack on the AES. In CT-RSA. [2] Ayush Agarwal, Sioli O’Connell, Jason Kim, Shaked Yehezkel, Daniel Genkin, Eyal Ronen, and Yuval Yarom. 2022. Spook.js: Attacking Chrome Strict Site Isolation via Speculative Execution. In S&P. [3] Tal Be’ery and Amichai Shulman. 2013. A Perfect CRIME? Only TIME Will Tell. In Black Hat Europe. [4] Daniel J. Bernstein. 2005. Cache-Timing Attacks on AES. http://cr.yp.to/ antiforgery/cachetiming-20050414.pdf [5] William Blair, William Robertson, and Manuel Egele. 2023. ThreadLock: Native Principal Isolation Through Memory Protection Keys. In AsiaCCS. [6] David Brumley and Dan Boneh. 2003. Remote Timing Attacks Are Practical. In USENIX Security. [7] Claudio Canella, Jo Van Bulck, Michael Schwarz, Moritz Lipp, Benjamin Von Berg, Philipp Ortner, Frank Piessens, Dmitry Evtyushkin, and Daniel Gruss. 2019. A Systematic Evaluation of Transient Execution Attacks and Defenses. In USENIX Security. [8] Cloudflare. 2021. The EPYC journey continues to Milan in Cloudflare’s 11th generation edge server. https://blog.cloudflare.com/the-epyc-journey-continuesto-milan-in-cloudflares-11th-generation-edge-server/ [9] Cloudflare. 2023. Cloudflare Limits. https://developers.cloudflare.com/workers/ platform/limits [10] Cloudflare. 2023. Cloudflare’s Gen 12 server: Bigger, better, cooler in a 2U1N form factor. https://blog.cloudflare.com/gen-12-servers/ [11] Cloudflare. 2024. A look at the Cloudflare Gen 13 server and its hardware. https://blog.cloudflare.com/gen13-config/ [12] Cloudflare. 2025. Cloudflare Sandbox SDK. https://developers.cloudflare.com/ sandbox/ [13] Cloudflare. 2025. Cloudflare Workers. https://www.cloudflare.com/products/ cloudflare-workers/ [14] Cloudflare. 2025. Cloudflare Workers - Durable Objects. https://developers. cloudflare.com/durable-objects/ [15] Cloudflare. 2025. Safe in the Sandbox: Security Hardening for Cloudflare Workers. https://blog.cloudflare.com/safe-in-the-sandbox-security-hardening-forcloudflare-workers/ [16] Cloudflare Workers. 2025. Security model. https://developers.cloudflare.com/ workers/reference/security-model/ [17] Emma Connor, Tyler McDaniel, Jared M Smith, and Max Schuchard. 2020. { PKU } pitfalls: Attacks on { PKU-based } memory isolation systems. In 29th USENIX Security Symposium (USENIX Security 20). 1409–1426. [18] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. 2022. Introduction to Algorithms (4th ed.). MIT Press. [19] Cloudflare Datamining. 2024. CDN-CGI-Dev.js. https://github.com/CloudflareMining/Cloudflare-Datamining/blob/main/scripts/src/cdn-cgi-dev.js [20] Cloudflare Datamining. 2024. Cloudflare Datamining Website. https://cfdata.lol/ [21] Fastly. 2025. Fastly Serverless Compute Environment. https://www.fastly.com/ edge-cloud-network/serverless/ [22] John Graham-Cumming. 2017. Incident report on memory leak caused by Cloudflare parser bug. https://blog.cloudflare.com/incident-report-on-memory-leakcaused-by-cloudflare-parser-bug/ [23] Samuel Gross. 2024. The V8 Sandbox. https://v8.dev/blog/sandbox [24] Daniel Gruss, Erik Kraft, Trishita Tiwari, Michael Schwarz, Ari Trachtenberg, Jason Hennessey, Alex Ionescu, and Anders Fogh. 2019. Page Cache Attacks. In CCS. [25] Daniel Gruss, Clémentine Maurice, and Stefan Mangard. 2016. Rowhammer.js: A Remote Software-Induced Fault Attack in JavaScript. In DIMVA. [26] Mohammad Hedayati, Spyridoula Gravani, Ethan Johnson, John Criswell, Michael L Scott, Kai Shen, and Mike Marty. 2019. Hodor: Intra-Process isolation for High-Throughput data plane libraries. In ATC. [27] James Kettle. 2024. Listen to the whispers: web timing attacks that actually work. https://portswigger.net/research/listen-to-the-whispers-web-timingattacks-that-actually-work [28] Darshana Jayasinghe, Jayani Fernando, Ranil Herath, and Roshan Ragel. 2010. Remote cache timing attack on advanced encryption standard and countermeasures. In ICIAFs. [29] Dougall Johnson. 2021. Another approach to portable Javascript Spectre exploitation. https://web.archive.org/web/20260114104803/https: //dougallj.wordpress.com/2021/03/16/another-approach-to-portablejavascript-spectre-exploitation/ [30] David A Kaplan. 2023. Optimization and Amplification of Cache Side Channel Signals. arXiv preprint arXiv:2303.00122 (2023). [31] Daniel Katzman, William Kosasih, Chitchanok Chuengsatiansup, Eyal Ronen, and Yuval Yarom. 2023. The gates of time: Improving cache attacks with transient execution. In USENIX Security. [32] Jason Kim, Jalen Chuang, Daniel Genkin, and Yuval Yarom. 2025. FLOP: Breaking the Apple M3 CPU via False Load Output Predictions. In USENIX Security.

Martin Schwarzl, Haocheng Xiao, Albert Pedersen, Sam Ainsworth, and Nigel Topham

for-spectre.html [62] Martin Unterguggenberger, Lukas Lamster, David Schrammel, Martin Schwarzl, and Stefan Mangard. 2024. TME-Box: Scalable In-Process Isolation through Intel TME-MK Memory Encryption. arXiv preprint arXiv:2407.10740 (2024). [63] Tom Van Goethem, Christina Pöpper, Wouter Joosen, and Mathy Vanhoef. 2020. Timeless timing attacks: Exploiting concurrency to leak secrets over remote connections. In USENIX Security. [64] Mathy Vanhoef and Tom Van Goethem. 2016. HEIST: HTTP Encrypted Information can be Stolen through TCP-windows. In Black Hat US Briefings. [65] Venkatanathan Varadarajan, Yinqian Zhang, Thomas Ristenpart, and Michael Swift. 2015. A placement vulnerability study in multi-tenant public clouds. In USENIX Security. [66] Pepe Vila, Boris Köpf, and Jose Morales. 2019. Theory and Practice of Finding Eviction Sets. In S&P. [67] Yingchen Wang, Riccardo Paccagnella, Elizabeth Tang He, Hovav Shacham, Christopher W. Fletcher, and David Kohlbrenner. 2022. Hertzbleed: Turning Power Side-Channel Attacks Into Remote Timing Attacks on x86. In USENIX Security. [68] Johannes Wikner, Cristiano Giuffrida, Herbert Bos, and Kaveh Razavi. 2022. Spring: Spectre Returning in the Browser with Speculative Load Queuing and Deep Stacks. In WOOT. [69] Haocheng Xiao and Sam Ainsworth. 2023. Hacky Racers: Exploiting InstructionLevel Parallelism to Generate Stealthy Fine-Grained Timers. In ASPLOS. [70] Ziqi Yuan, Siyu Hong, Rui Chang, Yajin Zhou, Wenbo Shen, and Kui Ren. 2023. Vdom: Fast and unlimited virtual domains on multiple architectures. In ASPLOS. [71] Xin-jie Zhao, Tao Wang, and Yuanyuan Zheng. 2009. Cache Timing Attacks on Camellia Block Cipher. Cryptology ePrint Archive (2009).

A

Nested-Loop Amplification Scaling

The nested-loop gadget of Listing 3 exposes two repetition counts. The inner loop (INNER_REP) drives the PLRU oscillation within a single iteration. The outer loop (OUTER_REP_NUM) repeats setup, transient leak, and amplification. Figure 9 shows the total measured timing as a function of the inner-loop repetitions. We measure a linear relation over the entire evaluated range. We conclude that the amplification factor is a directly controllable parameter. An attacker chooses INNER_REP to raise the timing difference above the resolution of the available remote timer. The attacker pays for this choice only in wall-clock time. Measured Linear fit

40 Total Time (ms)

[33] Jason Kim, Daniel Genkin, and Yuval Yarom. 2025. SLAP: Data Speculation Attacks via Load Address Prediction on Apple Silicon. In S&P. [34] Juhee Kim, Jinbum Park, Sihyeon Roh, Jaeyoung Chung, Youngjoo Lee, Taesoo Kim, and Byoungyoung Lee. 2024. TikTag: Breaking ARM’s Memory Tagging Extension with Speculative Execution. arXiv preprint (2024). [35] Jason Kim, Stephan van Schaik, Daniel Genkin, and Yuval Yarom. 2023. iLeakage: Browser-based Timerless Speculative Execution Attacks on Apple Devices. In ACM CCS. [36] Vladimir Kiriansky, Ilia Lebedev, Saman Amarasinghe, Srinivas Devadas, and Joel Emer. 2018. DAWG: A Defense Against Cache Timing Attacks in Speculative Execution Processors. In MICRO. [37] Ofek Kirzner and Adam Morrison. 2021. An Analysis of Speculative Type Confusion Vulnerabilities in the Wild. In 30th USENIX Security Symposium (USENIX Security 21). USENIX Association, 2399–2416. https://www.usenix.org/conference/ usenixsecurity21/presentation/kirzner [38] Paul Kocher, Jann Horn, Anders Fogh, Daniel Genkin, Daniel Gruss, Werner Haas, Mike Hamburg, Moritz Lipp, Stefan Mangard, Thomas Prescher, Michael Schwarz, and Yuval Yarom. 2019. Spectre Attacks: Exploiting Speculative Execution. In S&P. [39] Esmaeil Mohammadian Koruyeh, Khaled N Khasawneh, Chengyu Song, and Nael Abu-Ghazaleh. 2018. Spectre returns! speculation attacks using the return stack buffer. In 12th USENIX Workshop on Offensive Technologies (WOOT 18). [40] Michael Kurth, Ben Gras, Dennis Andriesse, Cristiano Giuffrida, Herbert Bos, and Kaveh Razavi. 2020. NetCAT: Practical Cache Attacks from the Network. In S&P. [41] Giorgi Maisuradze and Christian Rossow. 2018. ret2spec: Speculative execution using return stack buffers. In Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security. 2109–2122. [42] Ross Mcilroy, Jaroslav Sevcik, Tobias Tebbi, Ben L Titzer, and Toon Verwaest. 2019. Spectre is here to stay: An analysis of side-channels and speculative execution. arXiv preprint arXiv:1902.05178 (2019). [43] Microsoft. 2024. Introducing Hyperlight: Virtual machine-based security for functions at scale. https://opensource.microsoft.com/blog/2024/11/07/introducinghyperlight-virtual-machine-based-security-for-functions-at-scale/ [44] Tavis Ormandy. 2017. cloudflare: Cloudflare Reverse Proxies are Dumping Uninitialized Memory. https://project-zero.issues.chromium.org/issues/42450151 [45] Antoon Purnal, Marton Bognar, Frank Piessens, and Ingrid Verbauwhede. 2023. Showtime: Amplifying arbitrary cpu timing side channels. In AsiaCCS. [46] Hany Ragab, Enrico Barberis, Herbert Bos, and Cristiano Giuffrida. 2021. Rage Against the Machine Clear: A Systematic Analysis of Machine Clears and Their Implications for Transient Execution Attacks. In USENIX Security. [47] Charles Reis, Alexander Moshchuk, and Nasko Oskov. 2019. Site isolation: Process separation for web sites within the browser. In USENIX Security. [48] Thomas Ristenpart, Eran Tromer, Hovav Shacham, and Stefan Savage. 2009. Hey, You, Get Off of My Cloud: Exploring Information Leakage in Third-Party Compute Clouds. In CCS. [49] Maryam Rostamipoor, Seyedhamed Ghavamnia, and Michalis Polychronakis. 2025. KASPER: Scanning for Generalized Transient Execution Gadgets in the Linux Kernel. In NDSS. [50] Stephen Röttger and Artur Janc. 2021. A Spectre proof-of-concept for a Spectreproof web. https://leaky.page/blog [51] David Schrammel, Samuel Weiser, Richard Sadek, and Stefan Mangard. 2022. Jenny: Securing Syscalls for PKU-based Memory Isolation Systems. In USENIX Security. [52] David Schrammel, Samuel Weiser, Stefan Steinegger, Martin Schwarzl, Michael Schwarz, Stefan Mangard, and Daniel Gruss. 2020. Donky: Domain Keys–Efficient In-Process Isolation for RISC-V and x86. In USENIX Security. [53] Michael Schwarz, Clémentine Maurice, Daniel Gruss, and Stefan Mangard. 2017. Fantastic Timers and Where to Find Them: High-Resolution Microarchitectural Attacks in JavaScript. In FC. [54] Michael Schwarz, Martin Schwarzl, Moritz Lipp, Jon Masters, and Daniel Gruss. 2019. Netspectre: Read arbitrary memory over network. In ESORICS. [55] Martin Schwarzl, Pietro Borrello, Andreas Kogler, Kenton Varda, Thomas Schuster, Daniel Gruss, and Michael Schwarz. 2021. Dynamic Process Isolation. arXiv preprint arXiv:2110.04751 (2021). [56] Martin Schwarzl, Pietro Borrello, Andreas Kogler, Kenton Varda, Thomas Schuster, Michael Schwarz, and Daniel Gruss. 2022. Robust and Scalable Process Isolation Against Spectre in the Cloud. In ESORICS. [57] Martin Schwarzl, Pietro Borrello, Gururaj Saileshwar, Hanna Müller, Michael Schwarz, and Daniel Gruss. 2023. Practical Timing Side Channel Attacks on Memory Compression. In S&P. [58] Martin Schwarzl, Erik Kraft, Moritz Lipp, and Daniel Gruss. 2022. Remote Memory-Deduplication Attacks. In NDSS. [59] André Seznec. 2016. TAGE-SC-L branch predictors again. In CBP-5. [60] Igor Sheludko and Santiago Aboy Solanes. 2020. Pointer Compression in V8. https://v8.dev/blog/pointer-compression [61] Stephen Roettger and Artur Janc. 2021. A Spectre proof-of-concept for a Spectreproof web. https://security.googleblog.com/2021/03/a-spectre-proof-of-concept-

20

0

0

5k

10k

15k

20k

Number of Repetitions

25k

30k

·104

Figure 9: Total timing as a function of inner-loop repetitions for the nested-loop PLRU amplification.

B

Long-Term Timer Stability

To evaluate whether the timing signal remains distinguishable over an extended period, we measure the median cache-hit and cachemiss timing on the production system. We collect 253 ground-truth measurement sessions over 28 hours. Each session records rdtscp cycle counts for cache hits (lastTest0_1, lastTest1_0) and cache misses (lastTest0_0, lastTest1_1).

Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers

Figure 10 plots the per-session miss−hit timing difference over the full observation window. The difference remains strictly positive across the entire window. We measure a median of 1.17 ms (𝑛 = 253, 𝜎 𝜇 = 4.75%). The measurements also show a diurnal pattern. During afternoon hours, the production system is under heavy tenant load. Fewer sessions complete successfully, and the per-session difference shrinks toward the noise floor. After midnight, contention drops and the difference grows correspondingly larger. We conclude that the absolute leakage throughput is load-dependent. Still, the underlying signal never disappears. Miss − Hit [ms]

Median timing difference

4

Isolate and Object Memory Layout

0x10ea

0x10ec

0x10ee

0x10f0

0x10f2

0x10f4

0x10f6

0x10f8

0x10fa

0x10fc

midnight

2 0

C

We use the attack to verify the address allocation of isolate roots. We redeploy the script after each execution to create a new isolate. Figure 11 shows the isolate roots we leak over 10 consecutive runs. We observe a linear allocation with a 2 GiB offset between the newly allocated isolates. Moreover, we analyze the addresses of local and global objects within an isolate root. The addresses stay the same across script executions until we redeploy the script. The bump allocator in V8 places offsets within 256 KiB pages at the same positions.

12:00

00:00

12:00

Time (HH:MM)

Figure 10: Per-session miss−hit timing difference over 28 hours on the production system. The difference stays strictly positive across the entire window.

Figure 11: Leaked isolate roots, indicating linear isolate allocation within 2 GiB. Leaked objects sit at a fixed offset from the isolate root due to bump allocation, e.g., 0x10ea00077e24.

Related documents

Record · ID 463185 · SHA-256 77e60c8cc1e4c09b
Retrieved via Conceptio: every document is proof-bundled with source, license, and retrieval metadata.
Bring this data into your agent: Connect via MCP or API · 20 free credits to start · no card required
Read the Docs → · View CLI source on GitHub · Conceptio Open Knowledge Archive