WebRTC leaks: why your IP shows even with the VPN on
English
To set up peer-to-peer calls, WebRTC asks a STUN server what your public address looks like, and that request often slips past the VPN. How the leak works, why testing from China needs domestic STUN servers, and what turning WebRTC off costs you.
6 dk okuma · Yayımlanma: 10 Eylül 2026
You connect through your proxy, open an IP-lookup page, and it shows an address in Tokyo or Los Angeles. Reassuring. Meanwhile, JavaScript on that same page may already hold your real public IP back home. Not through a bug, but through a perfectly legitimate browser feature called WebRTC.
What WebRTC is for
WebRTC is the browser's built-in real-time communication stack. Video meetings in a tab, browser-based phone calls, peer-to-peer file transfers on some file-sharing sites: all of it runs on the RTCPeerConnection object. For two browsers to talk directly, each needs to learn what its own address looks like from the outside. That discovery process is called ICE, Interactive Connectivity Establishment.
ICE gathers a list of "candidates", which fall roughly into three kinds:
- host candidates: addresses on your own network interfaces, such as
192.168.1.23. - srflx (server-reflexive) candidates: your browser sends a UDP packet to a STUN server, and the server replies with the source address it saw. That is your public egress IP.
- relay candidates: traffic bounced through a TURN server. Usually needs credentials, and not relevant to the leak.
The important part: every candidate is handed to page script verbatim, through the onicecandidate event and the SDP text. The page never has to complete a call. Create an RTCPeerConnection, add a data channel, call createOffer, and a few hundred milliseconds later the candidate list sits in a JavaScript variable. No permission prompt, no indicator.
What STUN is
STUN is a mirror. You send it a UDP packet; it answers "I see you coming from 1.2.3.4:51234." The protocol is tiny and stateless, and there are plenty of public servers. Google's stun.l.google.com:19302 is the famous one; Cloudflare and Twilio run others. Because it is so simple, it is also the leak's entry point.
Why the VPN doesn't catch it
It depends on how your circumvention client takes over traffic.
Many clients run in system-proxy mode: they open a local SOCKS or HTTP port and point the operating system's proxy setting at it. Browser HTTP requests go through it obediently. WebRTC, though, sends raw UDP packets, and raw UDP never consults the proxy setting. The packet leaves through your default network interface, and the STUN server sees your home broadband IP.
Rule-based split tunnelling has the same problem. If only certain domains or IP ranges go through the proxy, STUN servers are rarely on that list, so they get direct connections. TCP-only proxy configurations leak UDP by definition.
"Browser-only" proxying, whether through an extension or a per-application proxy setting, behaves like system-proxy mode.
What actually blocks the leak is TUN, or "global", mode: the client creates a virtual network interface and rewrites the routing table so that every packet, regardless of protocol, enters the tunnel. Then STUN sees the exit node's IP, which matches what HTTP sees, and the test reports no leak.
A WebRTC test therefore tells you more than "leaked or not". It tells you how much of your traffic the tool really controls.
mDNS obfuscation: LAN addresses mostly stopped leaking
A few years ago WebRTC exposed your private LAN address in host candidates. A site could see whether you were on 192.168.x.x or 10.x.x.x, and make a fair guess about whether you were at home or in an office. Chrome and Firefox now replace those with mDNS names by default, so the candidate reads like a1b2c3d4-….local rather than an IP.
That fixed the private-address problem. The srflx candidate, the public IP, is not obfuscated, because ICE hole-punching genuinely needs it. In a current browser, "WebRTC leak" effectively means "public IP leak".
Why testing from China needs domestic STUN servers
Plenty of leak-test sites get this wrong.
Suppose the test page only queries Google's STUN server and you are on a direct connection inside mainland China, either because the proxy is off or because UDP is being routed around it. That packet will very likely be dropped or time out, no candidate comes back, and the page cheerfully says "no leak detected". Nothing leaked because the probe couldn't reach anything, which is not the same thing.
The reverse happens on the proxied side: Google's STUN is reachable through the tunnel, it returns the exit-node IP, and everything looks consistent. The direct path was never measured.
Browserscan's approach is to query a whole batch of STUN servers at once: overseas ones like Google, Cloudflare and Twilio, plus servers run by Chinese companies such as Xiaomi, QQ and bilibili. A domestic STUN server is always reachable on a direct connection from inside China, so if your UDP escapes the tunnel it will report your real broadband address. Our WebRTC check does the same: many servers in parallel, every returned public address compared against the IP seen at the HTTP layer, and any mismatch counts as a leak.
This also explains why someone can be "clean" on one test site and "leaking" on another.
How to protect yourself
In rough order of cost:
Let the tool take everything. Switch the client to TUN or global mode and turn on the kill switch, so a dropped tunnel cuts the connection instead of falling back to direct. This is the real fix and costs you no browser features.
Firefox. Type about:config in the address bar, search for media.peerconnection.enabled, set it to false. WebRTC is off entirely.
Chrome and Edge. There is no built-in toggle. Install Google's own WebRTC Network Limiter extension and choose "use only the default public interface" or "disable non-proxied UDP". uBlock Origin also has a setting labelled "Prevent WebRTC from leaking local IP addresses".
Safari. No user-facing switch; you have to solve it at the proxy layer.
Disabling WebRTC has real costs. Browser-based meetings (Google Meet, the web version of Tencent Meeting and the like) may fail to connect or only work through relays; web phones, in-browser P2P transfers and some web games break too. If you are in calls every day, "limit" is a better choice than "disable".
FAQ
The test shows my WebRTC public IP matches my HTTP IP. Am I safe? On this particular check, yes: UDP is going through the tunnel. It says nothing about DNS, which is a separate problem; see DNS leaks and open ports.
My candidates only contain .local names and no IP at all. What does that mean?
The browser applied mDNS obfuscation and received no srflx candidate: either every STUN server was unreachable or an extension is limiting WebRTC. The test can't conclude anything in that state, and "no result" is not "safe".
Does this happen on phones? Mobile browsers have WebRTC too. But mobile circumvention clients mostly run as system VPNs (TUN mode), which capture all traffic by design, so leaks are actually rarer than on desktop. Proxy-only style clients on iOS can still leak.