hi, i'm daniel. i'm a 15-year-old high school junior. in my free time, i hack billion dollar companies and build cool stuff.
3 months ago, I discovered a unique 0-click deanonymization attack that allows an attacker to grab the location of any target within a 250 mile radius. With a vulnerable app installed on a target's phone (or as a background application on their laptop), an attacker can send a malicious payload and deanonymize you within seconds--and you wouldn't even know.
I'm publishing this writeup and research as a warning, especially for journalists, activists, and hackers, about this type of undetectable attack. Hundreds of applications are vulnerable, including some of the most popular apps in the world: Signal, Discord, Twitter/X, and others. Here's how it works:
By the numbers, Cloudflare is easily the most popular CDN on the market. It beats out competitors such as Sucuri, Amazon CloudFront, Akamai, and Fastly. In 2019, a major Cloudflare outage knocked most of the internet offline for over 30 minutes.
One of Cloudflare's most used feature is Caching. Cloudflare's Cache stores copies of frequently accessed content (such as images, videos, or webpages) in its datacenters, reducing server load and improving website performance (https://developers.cloudflare.com/cache/).
When your device sends a request for a resource that can be cached, Cloudflare retrieves the resource from its local datacenter storage, if available. Otherwise, it fetches the resource from the origin server, caches it locally, and then returns it. By default, some file extensions are automatically cached but site operators can also configure new cache rules.
Cloudflare has a vast global presence, with hundreds of datacenters in 330 cities across 120+ countries—an estimated 273% more datacenters than Google. In the U.S. East region, for example, the nearest datacenter to me is less than 100 miles. If you live in a developed country, there's a good chance the nearest datacenter to you is less than 200 miles from you.
A few months ago, I had a lightbulb moment: if Cloudflare stores cached data so close to users, could this be exploited for deanonymization attacks on sites we don't control?
You see, Cloudflare returns information about a request's cache status in the HTTP response.
cf-cache-status
can be HIT
/MISS
and cf-ray
includes the airport code for the closest airport to the datacenter that handles the request (in my case, IAD).
If we can get a user's device to load a resource on a Cloudflare-backed site, causing it to be cached in their local datacenter, we can then enumerate all Cloudflare datacenters to identify which one cached the resource. This would provide an incredibly precise estimate of the user's location.
There was a one major hurdle I had to get through before I tested this theory.
You can't simply send HTTP requests to individual Cloudflare datacenters. For "security purposes" (presumably DDoS protection), all Cloudflare IP ranges are strictly anycast. All TCP connections opened to their network are always handled by the nearest available datacenter to you, there's no way you can ask a datacenter in Canada to handle your request if you live in the US.
However, after some research, I found a forum post (https://community.cloudflare.com/t/how-to-run-workers-on-specific-datacenter-colos/385851) from a community member showing me exactly how. The author shared a bug he found to send requests to specific Cloudflare datacenters with Cloudflare Workers.
I'm still not 100% sure of the specifics of this bug, but using an IP range used internally by Cloudflare WARP (Cloudflare's VPN client), we could ask certain datacenters to handle HTTP requests. Normally, this IP range blocked inbound connections from external IP addresses but requests sent from Workers could bypass this since the connection would originate from inside Cloudflare's network.
I spent a few minutes reading their post and I quickly spined up a tool for this: Cloudflare Teleport (https://github.com/hackermondev/cf-teleport). Certain IP ranges corresponded to different datacenters (https://github.com/hackermondev/cf-teleport/blob/main/scripts/data/colos.json).
Cloudflare Teleport is a proxy powered by Cloudflare Workers that redirects HTTP requests to specific datacenters. For example, https://cfteleport.xyz/?proxy=https://cloudflare.com/cdn-cgi/trace&colo=SEA would proxy a HTTP GET request to https://cloudflare.com/cdn-cgi/trace specifically to a Seattle (SEA) datacenter.
Cloudflare would end up completely patching this bug a few months later, making this tool obsolete, but more on that later. For a majority of my initial, I used this tool.
As soon as the Cloudflare Teleport tool was complete, I was able to confirm my theory. I coded a simple CLI program that would send an HTTP GET request to a specified URL and list all datacenters that had the resource cache and its age.
For my first test, I used Namecheap's favicon (https://www.namecheap.com/favicon.ico). This resource has Cloudflare Caching enabled, it's just a simple static image of their logo. (This was the quickest site I could find that didn't have rigorous bot protection):
Boom, it worked. Namecheap had configured their cache age extremely low (5 minutes) but I was able to see every datacenter that had cached the their site's favicon in the last 5 minutes. Since everytime you load their site, your browser automatically downloads this favicon, this means a user from each one of this locations has visited the Namecheap.com site within the 5 minutes with the last visit from Tokyo, Japan.
This was just meant to be a simple test and there's almost no impact here, but with this I confirmed my theory. This proved the concept of using Cloudflare caching for deanonymization attacks.
Signal, an open-source encrypted messaging service, is widely used by journalists and activists for its privacy features. Internally, the app utilizes two CDNs for serving content: cdn.signal.org
(powered by CloudFront) for profile avatars and cdn2.signal.org
(powered by Cloudflare) for message attachments.
When a user sends an attachment (e.g., an image) on Signal, it is uploaded to cdn2.signal.org. Once the recipient opens the conversation, their device automatically downloads the attachment. Since Cloudflare caching is enabled for these URLs, an attacker can use the cache geolocation method to pinpoint the recipient’s location.
The https://cdn2.signal.org/attachments/*
path is configured to cache responses with Cloudflare. This means once a user's device automatically downloads an attachment, it's possible for an attacker to run a cache geolocation attack to find out which local datacenter they're near--similar to how law enforcement track mobile devices through cell phone towers.
To test this, I quickly patched the Signal desktop app to remove SSL pinning and configured Burp to intercept and view HTTP requests/responses sent through the app.
This ensures that the app doesn't download attachments uploaded from the our side (the attacker) since that would cache them to our local datacenter and pollute the results. The best way I found to do this with Burp is to configure intercept rules for attachments, then leave request intercept on and deny all requests.
This should work with any attachment but images are automatically downloaded when the user opens the conversation so they work best. I used a simple 1x1.png image for this test. The upload request is sent to Signal's CDN and you can see the attachment url in Burp once we send the attachment in the conversation and Signal uploads it (ex. https://cdn2.signal.org/attachments/UjLld11tvaL16M8mrd86).
After the targets opens the conversation (verify this with read recipts), their device should download the attachment which in turn causes Cloudflare to cache the file in a local datacenter.
I ran this attack on myself, used the CLI tool I mentioned earlier with the attachment url and found local datacenters that had cached the attachment.
In my case, I'm in New York and one of the closest datacenters to me is Newark, NJ (EWR) which is about 150 miles from my actual coordinates.
With an innocent-looking attachment, an attacker can deanonymize users and find their location within an approximate radius.
Here's where things get interesting. Although the 1-click method works, it requires the user to open the Signal conversation. Is it possible to run this attack without a single user interaction? Enter push notifications.
Signal's mobile app has 3 push notification settings.
Push Notifications are triggered if the user receives a message while not actively on the Signal app. By default, the mobile app includes the author, and message when it sends a push notification to your device.
The image shown on the right of the notification is the attachment sent with the message from Signal.
If the target has push notifications enabled (which it is by default), they don't even have to open the Signal conversation for their device to download the attachment. Once the push notification is sent to their device, it automatically downloads the image from Signal's CDN triggering the local datacenter to cache the response.
An attacker can run this deanonymization attack any time and grab a user's current location without a single interaction.
Signal, like Telegram, is used by journalists, activists, whisteblowers from all over the world. The potiental for this attack is massive. This attack can be used to track Signal accounts, correlate identities, find employees meeting with journalists and much more.
During my research, another app I found vulnerable to this type of attack is Discord. Discord is a free app that allows users to communicate with each other through text, voice, and video. Although the app is targeted towards gamers, Discord has been in the news recently this past year for facilitating government leaks and Discord hosts a significant portion of cybercrime on the internet.
The 1-click aspect is very simple and fairly similar to Signal, I would say the impact is even wider with Discord. Discord allows users with a Nitro subscription (their $9.99/mo premium service) to use custom emojis in a variety of places: Messages, User Presence, Channels, etc. These custom emojis are loaded from Discord's CDN and are configured to be cached on Cloudflare. An attacker can use the same deanonymization attack with Signal to deanonymize users.
So, instead of sending an attachment in a Discord channel, an attacker can display a custom emoji in their user status and simply wait for the target to open their profile to run a deanonymization attack.
I've disclosed the entire HackerOne report I sent to Discord which has specific details, but I want to focus on the 0-click aspect here.
In Discord, mobile push notifications are sent for a variety of events (not just for messages recieved like Signal). For example, sending a friend request to a Discord user triggers a push notification on the user's mobile device.
Interestingly, even if the user is actively on Discord, friend request notifications are always sent to the user's mobile device.
How would a deanonymization attack be used with a friend request notification? Well, take a look at the notification.
When you recieve a friend request and Discord sends the notification to your device, it includes the user's avatar url to be shown with the notification. Your phone downloads the avatar url (without any user interaction) and displays it alongside the notification.
Discord has Cloudflare caching configured on the CDN path for avatar urls, which means we can simply do the same cache location attack mentioned earlier.
In Discord, the avatar URL format used in push notifications is: https://cdn.discordapp.com/avatars/{user_id}/{avatar_hash}
. The avatar URL format used in the website to display user avatars is slightly different (it always contains an image extension) (https://cdn.discordapp.com/avatars/{user_id}/{avatar_hash}.png
).
Both URLs leads to the same image but since images displayed in the app have a different path, they're cached separately. This ensures our results are not polluted and allows us to ensure we are finding the datacenter of a device that loaded the avatar through a push notification and not just the profile on the Discord app.
Just like that, we have the steps for a 0-click version of this attack for Discord:
- Change your user avatar. This randomizes your avatar hash and ensures your avatar URL has not been loaded by anyone yet, increasing the accuracy of the attack.
- Send a friend request to the target. Although there's a variety of ways to trigger push notifications with Discord, I choose friend requests because they are always sent regardless of whether the user is active on Discord. They also don't require any mutual server with the target, meaning you can practically do this with anyone on Discord.
- Use Cloudflare Teleport tool on the user avatar and find all local datacenters that have cached the avatar
I'm very familar with Discord's API and I realized I could automate every step in Discord's 0-click attack, and so I did.
Introducing GeoGuesser. This is a private Discord bot with a single command that takes a username, runs an attack with the steps mentioned earlier and returns the result entirely through Discord.
When the command is called, it uses my account credentials to access the Discord User API, changes the user avatar to a randomly generated image (to randomize the hash) and sends a friend request to a username specified. Finally, it uses a private API based on the Cloudflare Teleport CLI to run the same cache enumeration attack and displays the results directly on Discord, all in less than 30 seconds.
To show the extent of this attack, one of the first users I tried this attack on was Stanislav Vishnevskiy, Discord's CTO.
The bot sends a friend request to Stan, then waits a couple of seconds to ensure he receives the push notification.
It finds 2 local Cloudflare datacenters that have cached the avatar. This could mean he has multiple devices hooked up with his Discord account that recieved the push notification, or his device loaded the avatar twice and the requests were load balanced within different datacenters.
GeoGuesser, powered by the Google Maps API, generates a likely location of the user. It finds the midpoint between the 2 datacenters and draws 2 circles that signify his radius.
Discord's HQ is located in San Francisco, CA (which is in the outer circle) so this map is accurate. Stan is most likely located somewhere near the edge of the inner circle which is about ~300 miles.
This entire process took less than a minute to run. I'm sure Stan saw the notification on his phone, didn't think twice and simply dismissed it. This was just a simple attack but this attack, if calibrated, can be used to track and monitor Stan's location.
An attacker like this can be launched on any Discord user and it's almost undetectable.
I responsibly disclosed to the affected parties my research, hoping something would be done to protect or warn users against this type of deanonymization attack but I was mostly disappointed.
Signal instantly dismissed my report, saying it wasn't their responsibility and it was up to users to hide their identity: "Signal has never attempted to fully replicate the set of network-layer anonymity features that projects like Wireguard, Tor, and other open-source VPN software can provide".
I disagree with this. Signal markets itself as a privacy-first communication platform. While it does not claim to provide network-layer anonymity like Tor, users trust Signal to minimize privacy risks.
The vulnerability demonstrates that the platform unintentionally leaks information that could narrow down a user’s location within a few hundred miles. This leakage conflicts with the expectations of many privacy-conscious users who rely on Signal for more than just end-to-end encryption.
Telegram, another privacy-focused application, is completely invulnerable to this attack as (1) they use a custom in-house built protocol thats not reliant on HTTP and (2) don't rely on cloud providers like Cloudflare for caching.
Initially, Discord's Security Team promised to look into this and make changes to protect their users against this type of attack but eventually they also changed their position on this, citing this as a Cloudflare issue other consumers are also vulnerable to.
Cloudflare ended up completing patching the bug used by Cloudflare Teleport to traverse datacenters. The bug had been reported to their HackerOne program a year ago by another reporter, but they hadn't done anything about it back then since they didn't see any impact of traversing datacenters until I shared my research.
Cloudflare reopened the old report, resolved it and awarded a $200 bounty to my report and the original.
Although this is a step in the right direction, this doesn't actually fix the core issue here. Every attack shown in this write up has been done in the last 24 hours even though Cloudflare patched this bug weeks ago. Cloudflare patched the bug inside their network that facilitated datacenter traversal, but that's not the only way to easilly traverse datacenters all over the world.
24 hours after their patch, I reprogrammed Cloudflare Teleport to use a VPN instead. Numerous VPNs provide multiple locations that users can connect to which sends their traffic through servers in different parts of the world and these servers map to different Cloudflare datacenters all over the world.
I chose a VPN provider with over 3,000 servers located in various locations across 31 different countries worldwide. Using this new method, I'm able to reach about 54% of all Cloudflare datacenters again. While this doesn't sound like a lot, this covers most places in the world with significant population.
Cloudflare's final statement about this says they do not consider the deanonymization attack to be a vulnerability in their own systems and it is up to their consumers to disable caching for resources they wish to protect.
There's clearly a problem here as Cloudflare says consumers are responsible for protecting themselves against these types of attacks, while consumers (ex. Discord) are putting the blame on Cloudflare.
The potential for exploitation using this deanonymization attack is significant, especially for users in sensitive positions like journalists, activists, and privacy-conscious individuals. The attack leverages fundamental design decisions in caching and push notification systems, demonstrating how infrastructure meant to enhance performance can be misused for invasive tracking.
Although Cloudflare has patched the Teleport bug, and some applications like Discord and Signal may have implemented mitigation measures following my disclosure, the underlying risks remain. Any app using a CDN for content delivery and caching can still be vulnerable if the proper precautions aren’t taken.
This attack highlights how complex and interconnected the digital ecosystem has become. While CDNs improve performance and scalability, they also inadvertently introduce risks that can be exploited in novel ways. By raising awareness and promoting best practices, we can work together to minimize the potential for abuse.
For users in sensitive roles or those concerned about their privacy, the key takeaway is this: stay informed and vigilant. While no system is entirely foolproof, taking steps to limit your exposure can make a significant difference.