In-app reader
Blog AttacksEdgeResearch** +1 Show 1 more tags
** 4 Tags Show 4 tags
_**
Selected Tags
AttacksEdgeResearchVulnerabilities
All tags
Matching tags
No tags found
1.1.1.1
2FA
Abuse
Access
Access Control Lists (ACLs)
Accessibility
Account Takeover
Acquisitions
Addressing
Advanced Certificate Manager
Advanced DDoS
Advertising
Aegis
AEO
Africa
Afroflare
Agent Cloud
Agent Development Lifecycle
Agent Readiness
Agents
Agents Week
Agents Week 2026
AI
AI Bots
AI Gateway
AI Search
AI-SPM
AI WAF
AI Week
Alertmanager
Always Online
AMD
AMP
Analytics
Anonymous
Anti Malware
Anycast
API
API Gateway
API Security
API Shield
APJC
Apple
Application Security
Application Services
Area 1 Security
Argo Smart Routing
ASCII
Asia
Athenian Project
Atlassian
Attacks
Audit Logs
Austin
Australia
Authentication
Authy
Automatic HTTPS
Automatic Platform Optimization
Automation
AutoMinify
Auto Rag
Awards
AWS
Baidu
Bandwidth Alliance
Bandwidth Costs
Best Practices
Beta
Better Internet
BGP
Billing
Birthday Week
Blackbird
Black Friday
Bot Fight Mode
Bot Management
Botnet
Bots
BPF
Brand
Brand Protection
Brazil
Browser Insights
Browser Rendering
Browser Run
Bug Bounty
Bugs
BYOIP
Cache
Cache Purge
Cache Reserve
Cache Rules
California
Canada
Cap'n Proto
CAPTCHA
Careers
CASB
Categories
CDN
CDNJS
Certificate Authority
Certificate Pinning
Certificate Transparency
Certification
CFSSL
Challenge Page
ChatGPT
China
China Network
Christmas
Chrome
CIO Week
CISA
Claire
CLI
ClickHouse
Clientless
Clientless Web Isolation
Cloud Connector
Cloud Email Security
Cloudflare Access
Cloudflare Apps
Cloudflare Area 1
Cloudflare Calls
Cloudflare Email Service
Cloudflare for Campaigns
Cloudflare for SaaS
Cloudflare for Startups
Cloudflare Gateway
Cloudflare History
Cloudflare Images
Cloudflare Media Platform
Cloudflare Meetups
Cloudflare Network
Cloudflare One
Cloudflare One Client
Cloudflare One User Risk Score
Cloudflare One Week
Cloudflare OS
Cloudflare Pages
Cloudflare Polish
Cloudflare Queues
Cloudflare Realtime
Cloudflare Stream
Cloudflare Tunnel
Cloudflare TV
Cloudflare Workers
Cloudflare Workers KV
Cloudflare Workers KV (ES)
Cloudflare Workers (PT)
Cloudflare Zero Trust
Cloudforce One
Cloudy
Code Orange
Coinbase
Colombia
Community
Compliance
Compression
Config Rules
Configuration Management
Congestion Control
Connectivity
Connectivity Cloud
Consumer Services
Containers
Content Independence Day
Content Scanning
Context
Core
COVID-19
Crawler Hints
CrowdStrike
Cryptography
Crypto Week
CSAM Reporting
Customers
Customer Success
Customer Zero
CVE
CVE-2023-50387
Cyber Readiness
Cybersecurity
D1
Dashboard
Data
Database
Data Catalog
Data Center
Data Localization
Data Localization Suite
Data Loss
Data Loss Prevention
Data Platform
Data Privacy Day
Data Protection
Data Sovereignty
Data Transfer Bucket
DDoS
DDoS Alerts
DDoS Reports
Debugging
Deep Dive
Descaler
Design
Deskope
Developer Documentation
Developer Platform
Developers
Developer Spotlight
Developers Storage
Developer Week
Device Security
DevOps
DEX
Digital Experience Monitoring
Digital Forensics
Disrupt
Distributed
Distributed Systems
Distributed Web
Diversity
DLP
DMARC
DNS
DNS Filtering
DNS Flood
DNSSEC
DNS Security
Dogfooding
DoH
Domain Rankings
Domain Scoped Roles
dosd
Drupal
Due Process
Durable Execution
Durable Objects
Early Hints
Earth Day
eBPF
EC2
eCommerce
Edge
Edge Computing
Edge Database
Edge Rules
Education
Egress
Elastic
Elections
Election Security
Elliptic Curves
Email Routing
Email Security
Email Workers
EmDash
Emissions
Employee Resource Groups
Encrypted SNI
Encryption
Engineering
Enterprise
Entropy
EPYC
Ethereum
Europe
European Union
Events
Exploit
Fancy Bear
Fast Fonts
FCC
Feature Flags
FedRAMP
FedRAMP High
FedRAMP Moderate
Firefox
Firewall
Firmware
Florida
Football
Formal Methods
Forrester
Fortran
Foundation DNS
Founders' Letter
France
Fraud
Free
Freedom of Speech
Front End
Full Stack
Full Stack Week
Fun
Gartner
Gatebot
GA Week
GDPR
General Availability
Generative AI
Gen X
Geo Key Manager
Germany
GitHub
Go
Google Analytics
Google Cloud
Google Workspace
Government Innovation
Grace Hopper
Grafana
GraphQL
Green
Grinch
Growth
gRPC
Guest Post
Hackathon
Halloween
Hardware
HashiCorp
Hertzbleed
Heuristics
History
Holidays
Holocaust
Hong Kong
Hosting Con
Hostnames
HTTP2
HTTP3
HTTPS
Human Rights
Hurricane
Hybrid Cloud
Hyperdrive
IBM
ICANN
iCloud Private Relay
Identity
IETF
IETF Standards
IL4
Image Optimization
Image Recognition
Image Resizing
Image Storage
Impact
Impact Week
I'm Under Attack Mode
Incident Report
Incident Response
India
Indicators of Compromise
Indonesian
Inference
Infrastructure
Infrastructure as Code
Insights
Intel
Interconnection
Internal DNS
Internet Performance
Internet Quality
Internet Regulation
Internet Shutdown
Internet Summit
Internet Traffic
Internet Trends
Internship Experience
Intrusion Detection
Investors
IoCs
iOS
IoT
IPFS
IPsec
IPv4
IPv6
IRAP
Israel
Italy
IWD
JAMstack
Japan
JavaScript
Jengo
Jengo Policy
Joomla
Judeoflare
Kafka
Kernel
Keyless SSL
KeyTrap
Key Value
Killnet
Korea
Kubernetes
LangChain
Latency
Latin America
Latinflare
LavaRand
Lazarus group
Leaked Credential Checks
Legal
Legal Patents Sable
LGBTQIA+
Life at Cloudflare
Linux
Lisbon
Live Streaming
Llama
LLM
Load Balancing
Localization
Log4J
Log4Shell
Logging
Log Push
Logs
LUA
Machine Learning
Magecart
Magic Firewall
Magic Network Monitoring
Magic Transit
Magic WAN
Magic WAN Connector
Malicious JavaScript
Malware
Managed Components
Managed Rules
March of Cloudflare
MASQUE
MCP
Meerkat
MeetUp
Meris
Message Protocol
Mexico
Micro-frontends
Microsoft
Microsoft 365
Microsoft Azure
Middle East
Migration Hub
Milestones
Miniflare
Mirage
Mirai
Mitel
Mitigation
Mixed Content Errors
MLops
Mobile
Mobile SDK
Model Context Protocol
Moldova
Monitoring
Multi-Cloud
Multi-User
MySQL
NaaS
Net Neutrality
Network
Networking
Network Interconnect
Network Performance Update
Network Protection
Network Services
New Year
NGINX
Ninjas
NIST
Node.js
North America
Notebooks
Notifications
NSEC3
OAuth
Observability
Oceania
OCSP
Offices
Okta
Olympics
Onboarding
OpenAI
Open API
OpenBMC
OpenDNS
Open Source
OpenSSL
OpenTelemetry
Optimization
Origin Rules
Outage
Oxy
Pacific Northwest
Page Rules
Page Shield
Parallels
Partners
Partnership
Password-reuse
Passwords
Passwords (PT)
Patents
PAYGO
Payments
Pay Per Crawl
PCI Certified
Peering
Performance
Phishing
php
Phython
Pingora
Pipelines
PlanetScale
Plans
Platform Engineering
Platform Week
Plesk
Policy & Legal
Politics
Portugal
Postgres
Post Mortem
Post-Quantum
Precursor
Prepared Statements
Prisma
Privacy
Privacy Pass
Privacy Week
Private IP
Private Network
Product Design
Product News
Programming
Programming (PT)
Project Fair Shot
Project Galileo
Project Honey Pot
Project Pangea
Project Safekeeping
Project Turpentine
Prometheus
Protocols
Proudflare
Proxying
Public Sector
Python
Python Workers
Quantization
Queues
QUIC
QUICHE
Quicksilver
R2
R2 Super Slurper
Radar
Radar Alerts
Radar API
Radar Maps
Railgun
Randomness
Ransom Attacks
Rapid Reset
Raspberry Pi
Rate Limiting
RC4
RDDoS
React
Reading List
Real-time
Recruiting
Regional Services
Registrar
Reliability
Remote Browser Isolation
Remote Desktop Protocol
Remote Work
Replication
Research
Resolver
Restreaming
Retreat
Reverse Engineering
REvil
Risk Management
Road to Zero Trust
Rocket Loader
RocksDB
Routing
Routing Security
RPC
RPKI
RRDNS
RSA
Russia
Rust
Rust Workers
SaaS
SAAS Security
Sable
Salt
Sampling
Sandbox
SASE
Save The Web
SDK
Search Engine
Secrets Store
Secure Web Gateway
Security
Security Analytics
Security Center
Security Posture
Security Posture Management
Security Service Edge
security.txt
Security Week
SEO
Serverless
Serverless AI
Serverless (PT)
Serverless Week
Server Push
Servers
SIEM
Signed Exchanges (SXG)
SIM
Singapore
Single Sign On (SSO)
Smart Placement
Smart Shield
Snippets
SOC as a Service
South Africa
South America
Spain
spdy
Spectrum
Speed
Speed Brain
Speed & Reliability
Speed Week
Spoofing
Sports
SQL
SRE
SSE
SSH
SSL
Standards
Startup Enterprise Plan
Statistics
StopTheHacker
Storage
Sumo Logic
Super Bowl
Supercloud
Supply Chain Attacks
Support
Sustainability
SWAG
SWG
Swift
Switzerland
SXSW
SYN
SYN Flood
Syria
TCP
Team
Teams Dashboard
TechCrunch
Technical Writing
Tech Talks
Terraform
Testimonials
Testing
Texas
Thanksgiving
The Serverlist Newsletter
Threat Data
Threat Feeds
Threat Intelligence
Threat Operations
Threat Report
Threats
Tiered Cache
TikTok
TLS
TLS 1.3
Tools
Tor
Tracing
Traffic
Transform Rules
Transparency
Trends
Trust & Safety
TTFB
TTL
TURN
TURN Server
Turnstile
TypeScript
UDP
Ukraine
United Kingdom
Universal SSL
URL Scanner
USA
User Research
VDI
Vectorize
Vetflare
Video
Visibility
Vite
VoIP
VPC
VPN
Vulnerabilities
WAF
WAF Attack Score
WAF Rules
Waiting Room
WARP
WARP Connector
WASM
Web3
Web Application Firewall
WebAssembly
Web Asset Discovery
Webinars
WebMCP
WebP
WebRTC
WebSockets
Wildebeest
Womenflare
WordPress
Workers AI
Workers Launchpad
Workers Logs
Workers Observability
Workers Sites
Workers Unbound
Workers VPC
Workflows
World IPv6 Day
Wrangler
x402
Year in Review
Z3
Zaraz
Zero Day Threats
Zero Trust
Zero Trust Week
Zone Versioning
Vulnerabilities
AttacksEdgeResearchVulnerabilities
August 19, 2026
**Martin Schwarzl and **Albert Pedersen
17 minute read
** COPY URL
In 2021, we assessed remote Spectre attacks against Cloudflare Workers. Based on the results, we shipped a production defense called Dynamic Process Isolation (DyPrIs), which identifies maliciously looking scripts and isolates them into separate processes. Since then, newer techniques in the area of stabilizing Spectre attacks have been discovered. To understand if these techniques posed a threat to our Workers production environment, we decided to internally reassess the remote Spectre attack. Building an updated proof-of-concept on the production environment allowed us to empirically assess the risk of Spectre attacks under production workloads.
To mount a successful side-channel attack in production, an external attacker has to overcome additional obstacles such as activity on shared hardware resources, interrupts, context switches, and coarse-grained timers. Our research uncovered a limitation in the implementation of DyPrIs and we managed to demonstrate a remote Spectre attack reliably leaking up to 12 bit/s with a 99% accuracy in the production environment of Cloudflare Workers. As a consequence of this research, we improved DyPrIs, integrated the V8 Sandbox and an in-process isolation mechanism to further reduce the risk of memory disclosure attacks.
Today we are publishing a paper describing our findings, co-authored by Albert Pedersen, Haocheng Xiao, Sam Ainsworth, Nigel Topham, and Martin Schwarzl. This paper covers research done in 2024 and early 2025.
Note that the presented attack is mitigated already in the production system due to countermeasures applied by Cloudflare Workers Runtime team. We did not find any indicators of active exploitation over the last three years.
Cloudflare Workers runs untrusted JavaScript on the edge. Leveraging language-level isolation, in the form of V8 isolates, tens of thousands of tenants can share the same operating-system process. Each Worker has its own separate JavaScript heap. This design keeps startup latency low and lets us run many tenants very efficiently compared to full process isolation. Around the runtime we have multiple layers of defense such as automated V8 patch pipelines, a two-layered sandbox consisting of Linux namespaces and seccomp filters, Cap’n Proto RPC, and the possibility to schedule certain scripts in separate process sandboxes. Still, a single arbitrary read vulnerability within a Worker process can lead to cross-tenant leakage. One vulnerability that is very hard to mitigate exploits the nature of speculative execution, namely in-process Spectre.
You can think of speculative execution in terms of hiking. At some point you arrive at a branch and have to predict where to go. If the prediction was correct, you saved some time and could enjoy the sun and a refreshing drink at a mountain hut. However, if you speculate in the wrong direction, you have to turn back. The trail looks untouched, but your footsteps remain in the mud.
Speculative execution in CPUs works similarly. The branch prediction performs an educated guess about a branch’s outcome ahead of time and the CPU speculatively executes it. If the prediction was correct, speculative execution saved some time. However, if the prediction is incorrect, the CPU has to discard the results, roll back and execute the other branch. Because these speculatively executed instructions only exist temporarily in the CPU pipeline and are never permanently retired or committed, the literature refers to them as transient instructions and generalizes the concept as transient execution.
However, due to the transient execution, there are still some traces left in the microarchitectural state for instance in CPU caches. Thus, an attacker can use Spectre to transiently access memory out of bounds, encode a single bit of information into the cache state and exploit the latency of reaccessing data to infer whether the bit was set or not.
To mitigate against in-process Spectre attacks, Cloudflare Workers freezes local timers, disallows multithreading and shared memory and actively detects, periodically shuffles memory and isolates malicious-looking scripts into separate processes.
The Cloudflare Workers platform deliberately restricts timers. During CPU-only execution, time is effectively frozen. Date.now() and performance.now() do not provide a continuously advancing high-resolution clock. There is no shared memory and no multithreading, so the classic counter-thread timer via a SharedArrayBuffer is not available.
To successfully mount an attack, several challenges have to be solved. First, Workers runtime is limited and co-location between an attacker and victim has to be guaranteed. Second, a reliable, ideally co-located, remote timer has to be discovered, which allows stable timing measurements. Third, the attack runs under production conditions, meaning it requires additional stability measures such as a reliable Spectre gadget enabling transient 64-bit out-of-bounds accesses, robust signal amplification to deal with systems and networking noise, and a primitive to reliably evict data out of the cache.
return probeArray[
obj instanceof ObjP
? PROBEARRAY_OFFSET + ((obj.ptr[0] >> bit) & 1) * 0x800
: 0x400
];
**
Speculative type confusion Spectre gadget
With the right Spectre gadget (snippet above), an attacker can transiently access out-of-bounds memory and encode a single bit into the cache (probeArray). The attacker then measures the memory access latency to confirm whether data has been cached or not. A faster access means the line was cached and the bit was 1. Conversely, a slower access means it was uncached and the bit was 0. In our attack, we use two different Spectre gadget types. The first one leaks compressed heap pointers, e.g., the isolate’s heap base address (root), and the other one leverages a speculative type confusion to leak from an arbitrary, attacker-crafted userspace 64-bit pointer. At the time of performing the research, the V8 Sandbox was not yet implemented at Cloudflare Workers. Under pointer compression, most objects use 32-bit compressed pointers. TypedArray was one of the few exceptions that still stored a raw 64-bit pointer to its backing store, which is exactly what our gadget abuses.
The branch obj instanceof ObjP performs a type check, i.e., a branch. To mistrain the branch prediction, we call the gadget many times on real ObjP instances, then call it on a different object with an attacker-controlled memory layout ObjI. The CPU speculates on the taken branches and follows obj.ptr[0], even though the object has a different type. To leak a single bit, we mask out one bit and use it to select one of two probeArray lines. Whether that line is cached encodes the bit.
Exploiting the heap leakage gadget, we map neighboring objects and locate an attacker-controlled array. Our second gadget confuses two large objects that span several cache lines, so the type field lands on a different cache line than the field we read. Evicting the type field opens the speculation window while the target field stays cached, and the transient read follows an attacker-controlled 64-bit value. That turns the leak into an arbitrary-address read. A more thorough description of this technique can be found in the paper.
Local demo of leaking an arbitrary 64-bit address.
A cache hit and a cache miss differ by a few nanoseconds. Moreover, a remote timer is noisy at the scale of a few microseconds up to a few milliseconds. Therefore, some form of signal amplification is required to differentiate a cache hit from a miss. Stephen Röttger and Artur Janc discovered a way to amplify a single memory access, by exploiting the tree-based pseudo least recently used (PLRU) cache-replacement policy in L1 caches. Tree-based PLRU organizes each cache set as a binary tree whose nodes point to the side used least recently, so the CPU evicts by following those pointers. With the right access pattern, an attacker can keep a target line cached indefinitely by touching its tree neighbor whenever the pointers turn toward the target. Quite elegant, right? Leveraging that behavior, the timing of a single cache event can be arbitrarily amplified such that it leads to a lot of L1 hits (faster) compared to lots of L1 misses in the opposite case.
The figure below illustrates whether a memory address X is cached or not. If it’s not cached, the access pattern leads to a lot of cache hits. If it is present, it occupies one node in the tree, and subsequently four cache lines try to fit into three nodes, which results in a lot of L1 misses.
As long as the signal can be amplified, a noisy remote timer is sufficient to differentiate an encoded bit. For instance, a WebSocket connection to an external server serving high-resolution timestamps is enough. The timer could be hosted at Cloudflare or at a co-located data center to the target data center running the Worker. The Worker asks the remote timer to mark a timestamp for a certain event and compute the delta for another request once the event has stopped.
In the paper, we evaluated several different timer setups and were able to reliably achieve sub-ms resolutions on the Median with only a handful of samples even over larger topological distances. The figure below shows an amplified cache event using the tree-based PLRU amplification.
A single measurement is not enough to differentiate timing-encoded data reliably. Production machines are noisy, thus an attacker has to repeat each measurement at least a few times and use some statistical discriminator. Repeating a measurement in our case means resetting the cache state. Two things have to be uncached before each round. The value the speculative branch depends on has to be evicted, so branch resolution stalls long enough to open a speculation window. The probe line that encodes the leaked bit has to be evicted, so the next transient access can re-cache it.
Since there is no direct instruction available in JavaScript, the classic way to do this is to build an eviction set. An eviction set is a group of addresses that map to the same cache set as the target. Accessing them in the right pattern pushes the target out of the cache. In their attack, Stephen Röttger and Artur Janc used an eviction list to reliably evict at least into the L2 cache. This works, but it is expensive. Constructing a precise eviction set requires many timed measurements, and our timer is a noisy remote timer. The previous remote attack against Workers sidestepped the search by traversing an array larger than the L1 and L2 caches on every round. That is an option, but even slower.
Dougall Johnson described a more elegant way in his really cool blog post on portable JavaScript Spectre exploitation. The idea follows directly from the pigeonhole principle. If you allocate far more data than the cache can hold, a randomly chosen cache line is almost certainly not cached. For a 256 KB L2 cache, allocating 64 MB leaves at most a 1/256 chance that a random cache line is still in L2. So instead of evicting a specific line, you never evict at all. You pick a fresh random location that is already evicted with overwhelming probability. The cool side effect of looping frequently over that array of objects is that this will lead to an auto-eviction effect.
To leverage this in JavaScript, we allocate a large pool of attacker and victim object pairs that exceeds the last-level ca
…(truncated for reading performance)
Discussion
Sign in to join the discussion.
Keep reading
Optional: create a free account to save items, track programs, and sync across web + app. Reading stays free.