Cloudflare WARP is a VPN-style product that routes user traffic through Cloudflare’s network before it exits to the internet. In its enterprise form (Zero Trust, with Gateway policies), Cloudflare terminates TLS at its edge and inspects HTTP to apply content policies. Tor is a separate anonymity system that routes TCP traffic through three encrypted relays so the destination sees only the final exit node, never the origin. The two are different layers solving different problems. Some users stack them, hoping for WARP’s performance and policy benefits plus Tor’s anonymity.
The stack does not work the way the stacker hopes. Cloudflare’s edge terminates TLS before the traffic enters Tor, and it stamps five HTTP headers into the request body, including Cf-Connecting-Ip — the user’s real IP. Tor encrypts the TCP stream but does not inspect HTTP. The headers ride inside the encrypted payload, invisible to onion routing, and arrive intact at the destination on a port with no Cloudflare infrastructure in the path. The result is that any service receiving WARP-fronted traffic through Tor sees the visitor’s real address in plain text, despite the three Tor hops in between.
In December 2025, Johannes Ullrich at SANS ISC observed Cf-Warp-Tag-Id in honeypot traffic. The work below extends his: the tag persists across IPs, survives Tor transit, and reaches non-Cloudflare destinations carrying the sender’s real address. For anyone running a service whose threat model assumes Tor anonymity for incoming connections, the implication is structural, not incidental.
The evidence
Five Cloudflare headers on every request:
Cf-Connecting-Ip: 65.109.30.32
Cf-Warp-Tag-Id: b87b4e0d-XXXX-XXXX-XXXX-5c7413e6d372
Cf-Ipcountry: FI
Cf-Ray: 9e5111121b0fe7bc-FRA
Cdn-Loop: cloudflare; loops=1Cf-Connecting-Ip is the IP that connected to WARP. Not the Tor exit. The real origin. Set server-side, overwrites client values.
Cf-Warp-Tag-Id is tied to the WARP enrollment. Undocumented, absent from Cloudflare’s headers reference.
Cf-Ipcountry is the GeoIP of the connecting IP.
Cf-Ray is a per-request ID with datacenter suffix (FRA, CDG).
Cdn-Loop confirms Cloudflare transit. Present on our server despite no Cloudflare relationship.
We verified: no cloudflared, no Tunnel, no proxy. Docker NATs directly to the container. Headers injected upstream.
Two hours later, a second session from a different network: residential IPv6, Free SAS (AS12322, French ISP), Chrome 146, fr-FR.
Cf-Connecting-Ip: 2a01:e0a:fe2:4de0:fac:5473:377e:1cde
Cf-Warp-Tag-Id: b87b4e0d-XXXX-XXXX-XXXX-5c7413e6d372
Cf-Ipcountry: FR
Cf-Ray: 9e51cabb2dd36ffa-CDGEverything changed except Cf-Warp-Tag-Id. One tag linked a VPS in Helsinki to a home connection in Paris, through six Tor exits.
The Finnish IP is real. We saw it connect directly ten days earlier. The French IPv6 is a residential ISP assignment. Someone routed their home connection through WARP and Tor, and their real IPv6 arrived in a header they almost certainly did not know existed.
How WARP defeats Tor
WARP creates a WireGuard tunnel to Cloudflare’s edge. In managed deployments (Zero Trust, Gateway), Cloudflare terminates TLS, inspects HTTP, and stamps headers before forwarding.
When the next hop is Tor:
Client
-> WARP (WireGuard)
-> Cloudflare Gateway
stamps: Cf-Connecting-Ip,
Cf-Warp-Tag-Id,
Cf-Ray, Cf-Ipcountry,
Cdn-Loop
-> Tor SOCKS
-> Entry -> Middle -> Exit
-> Destination
full HTTP, all five headersTor encrypts TCP streams. No relay parses HTTP. The headers are bytes inside the payload, invisible to onion routing.
Not a Tor vulnerability. Tor works as designed. WARP operates at HTTP, above Tor’s reach.
Any HTTP proxy that stamps identifying headers before Tor will leak them through Tor. WARP is the most widely deployed service that does this.
A 2023 test found WARP “adds no extra headers.” That test used the consumer 1.1.1.1 app. Managed WARP through Gateway performs TLS inspection. Different behavior. Cloudflare does not document the distinction.
For defenders
Three hunt rules drop out of the evidence, ordered by what each one detects.
Rule 1, transit detection. Cdn-Loop: cloudflare; loops=1 on a non-Cloudflare server means the request transited Cloudflare. This is the floor: every WARP-fronted request carries it.
Rule 2, real-origin extraction. Cf-Connecting-Ip on a non-Cloudflare server is the real origin behind WARP. Log it; it is the IP your visitor would not show you otherwise.
Rule 3, cross-session correlation. Same Cf-Warp-Tag-Id UUID across multiple source IPs means a shared WARP enrollment. In our two sessions, this header correlated a VPS in Helsinki and a residential IPv6 in Paris that six Tor relays should have made unlinkable.
A clarifying note for defenders whose own service sits behind Cloudflare: these headers are normal there, that is how Cloudflare passes client identity through to your origin. The leak is what arrives at a server that is not behind Cloudflare and still sees them.
For users at the other end of this stack: WARP through Tor is a worst-of-both anonymity posture. You inherit the attribution of WARP and the latency of Tor with the anonymity of neither.
Limitations
The architectural claim is high-confidence: HTTP header injection before a TCP anonymizer is a layer mismatch by construction, and Tor cannot inspect what is below it. The mechanism does not depend on a single observation.
The persistence claim for Cf-Warp-Tag-Id is medium-confidence: it rests on one UUID across two IPs, two hours apart, n=1. Not reproduced under controlled conditions. Consumer WARP (1.1.1.1) may not inject these headers; managed WARP through Gateway does. No public Cloudflare documentation exists on tag semantics or rotation.
Acknowledgments
Johannes Ullrich’s SANS ISC diary 32532 first observed Cf-Warp-Tag-Id in honeypot traffic (December 2025) and pointed at the WARP-Gateway distinction this post extends. The honeypot runs a fork of Beelzebub by Beelzebub.AI, extended for AI-targeted telemetry.