A revisit of remote Spectre attacks on Cloudflare Workers¶
Summary¶
In 2021 Cloudflare assessed remote Spectre attacks against Cloudflare Workers and shipped a production defense, Dynamic Process Isolation (DyPrIs). Because newer techniques for stabilizing Spectre attacks had since appeared, Cloudflare's Workers Runtime team re-ran the assessment on the production environment (research done 2024–early 2025, paper published 2026-08-19). Building an updated proof-of-concept against production let them empirically measure the risk under real workloads — activity on shared hardware, interrupts, context switches, and deliberately coarse timers. They found a limitation in the DyPrIs implementation and demonstrated a remote Spectre attack that reliably leaked up to 12 bit/s at >99% accuracy in production, leaking a JWT token placed in a co-located victim Worker. In response they improved DyPrIs, integrated the V8 Sandbox, and deployed an in-process isolation mechanism (MPK). The attack is already mitigated in production; no evidence of active exploitation was found over the prior three years.
Key takeaways¶
- Workers' density model is the threat surface. Tens of thousands of tenants share one OS process via V8 isolates (each Worker has its own JS heap). This is what keeps startup latency low and fleet density high, but a single arbitrary-read primitive inside one Worker process can leak cross-tenant — and in-process Spectre is exactly such a primitive that is very hard to mitigate because it exploits the CPU's speculative execution. (Source: sources/2026-08-19-cloudflare-a-revisit-of-remote-spectre-attacks-on-cloudflare-workers)
- The platform deliberately removes the easy timers, so the attacker imports one. During CPU-only execution, time is effectively frozen:
Date.now()/performance.now()do not advance at high resolution, there is noSharedArrayBuffercounter-thread timer, no shared memory, no multithreading. A remote timer — e.g. a WebSocket to an external server serving high-resolution timestamps, ideally co-located with the target datacenter — is sufficient as long as the signal is amplified. This is a remote timing side-channel. - Two gadget types turn a leak into an arbitrary-address read. Gadget 1 leaks compressed heap pointers (e.g. the isolate heap base / "root"). Gadget 2 is a speculative type-confusion gadget: mistrain an
obj instanceof ObjPbranch on real instances, then call it on an attacker-crafted object so the CPU transiently followsobj.ptr[0]under the wrong type, masking one bit into one of twoprobeArraycache lines. Under V8 pointer compression most objects use 32-bit compressed pointers, butTypedArraystill stored a raw 64-bit pointer to its backing store — exactly the structure gadget 2 abuses to follow an attacker-chosen 64-bit pointer. - Signal amplification via tree-PLRU makes a noisy remote timer usable. A cache hit vs miss differs by nanoseconds; a remote timer is noisy at microsecond–millisecond scale. Using the tree-based pseudo-LRU (PLRU) L1 replacement policy (Röttger & Janc's technique), an attacker can keep a target line cached indefinitely by touching its tree neighbor, converting one cache event into many L1 hits (or, if the line is present, four lines contending for three PLRU nodes → many L1 misses). This turns a single amplified access into a distribution separable even over a noisy network timer.
- The pigeonhole eviction trick avoids building eviction sets. Rather than construct a precise eviction set (expensive with a noisy remote timer) or traverse an oversized array every round (slower), allocate far more data than the cache can hold and pick a fresh random attacker/victim object pair each round — for a 256 KB L2, allocating 64 MB leaves ≤1/256 chance a random line is still cached (Dougall Johnson's portable-Spectre idea). Looping over the pool also auto-evicts.
- Co-location is trivial on Workers.
fetch("https://victim.example")from the attacker Worker usually causes the scheduler to spin up the victim isolate in the same process on the same edge server; keep it alive with periodic subrequests. Because attack stability depends on edge-server CPU load, an attacker can pick an off-peak colo (e.g. an Australian colo during European business hours) for low traffic. - Durable Objects defeat the per-invocation resource limits. Relevant limits at the time were 30s CPU time and 1,000 subrequests per invocation, reset per fetch event — but landing sequential requests on the same edge server is unreliable. Durable Objects treat every incoming WebSocket message as an invocation that resets those limits, giving a persistent bidirectional channel and keeping one isolate alive 5 to >20 hours (yielding to the event loop between synchronous bursts, since a >30s synchronous block gets the isolate killed).
- Why DyPrIs didn't catch it. (a) DyPrIs isolates a script only after its invocation finishes, but the Durable-Object WebSocket keep-alive holds a single invocation open for hours — the leak completes long before post-execution isolation kicks in. (b) DyPrIs normalizes branch mispredictions by iTLB accesses; the remote-timer I/O loop inflates iTLB activity (WebSocket traffic), pushing the normalized ratio below the detection threshold so the attack looks like an ordinary I/O-heavy Worker.
- The fix is three-layered defense in depth. (a) V8 Sandbox removes raw 64-bit pointers from large parts of the heap so
TypedArray-style gadgets no longer expose the raw backing-store pointer — the specific 64-bit leak gadget no longer works (though it is not a complete Spectre mitigation). (b) MPK-based in-process isolation (deployed Sept 2025) puts each isolate heap behind a hardware-enforced access boundary — a mis-keyed page access is denied by hardware, blocking the straightforward cross-isolate heap read (finite hardware domains, careful key-state management remain limits). (c) Improved DyPrIs treats long-lived executions and I/O-heavy workloads as first-class security cases (detection can't wait for a script to finish) and is investigating adding remote-timer behavior as a detection dimension.
Operational numbers¶
- Prior (2021-era) attack: ~120 bit/h (relied mostly on repetition).
- This work: up to 12 bit/s leak rate at >99% accuracy in production (higher rates possible at lower accuracy).
- First leaked byte of a JWT was
e=0b01100101, recovered bit-by-bit via a two-sided test + majority vote + percentile threshold. - Eviction math: 256 KB L2 → allocate 64 MB → ≤1/256 chance a random line is still cached.
- Isolate keep-alive via Durable-Object WebSocket: 5 to >20 hours; synchronous block limit 30 s before the runtime kills the isolate.
- Limits defeated: 30 s CPU/invocation, 1,000 subrequests/invocation (since raised).
- V8 Sandbox not yet deployed at research time; MPK in-process isolation deployed September 2025.
- Paper co-authors: Albert Pedersen, Haocheng Xiao, Sam Ainsworth, Nigel Topham, Martin Schwarzl (arXiv 2608.17043).
Systems / concepts / patterns extracted¶
- Systems: systems/cloudflare-workers, systems/v8-javascript-engine, systems/workerd, systems/dynamic-process-isolation (DyPrIs), systems/v8-sandbox, systems/cloudflare-durable-objects.
- Concepts: spectre-attack, speculative-execution (incl. transient execution), concepts/side-channel-attack, timing-side-channel, concepts/tenant-isolation, memory-protection-keys, concepts/defense-in-depth, concepts/memory-safety.
- Patterns: defense-in-depth-style layering (V8 Sandbox + MPK + DyPrIs), each layer compensating for the others' failure modes.
Caveats¶
- The demonstrated attack is already mitigated in production; Cloudflare found no indicators of active exploitation over the prior three years, and the PoC was run against Workers they controlled.
- Leak rate/accuracy figures are for controlled attacker+victim Workers under production conditions; higher machine utilization (peak hours) slows the attack but does not stop it.
- Neither the V8 Sandbox nor MPK is a complete Spectre mitigation — the paper is explicit that other variants/gadgets may still exist; the response is layered risk reduction, not elimination.
- MPK has a finite number of hardware protection domains and requires careful protection-key state management.
Source¶
- Original: https://blog.cloudflare.com/revisiting-spectre-attacks-on-workers/
- Paper: arXiv:2608.17043
- Raw markdown:
raw/cloudflare/2026-08-19-a-revisit-of-remote-spectre-attacks-on-cloudflare-workers-7e3762c6.md
Related¶
- systems/cloudflare-workers — the multi-tenant V8-isolate compute tier under attack.
- systems/v8-javascript-engine — pointer compression +
TypedArrayraw backing-store pointer is the gadget substrate. - systems/dynamic-process-isolation — DyPrIs, the 2021 defense whose limitations this work exposed and then fixed.
- systems/v8-sandbox — removes raw 64-bit heap pointers; part of the fix.
- spectre-attack — the class of attack.
- speculative-execution — the CPU behavior Spectre abuses.
- timing-side-channel — remote-timer + PLRU amplification channel.
- concepts/tenant-isolation — the cross-tenant boundary Spectre crosses in a shared process.
- memory-protection-keys — MPK, the hardware in-process isolation layer.
- concepts/defense-in-depth — the three-layer response.
- companies/cloudflare — author.