Guides ·
WebRTC leaks: what they are, how to test, and what each browser does
WebRTC is the browser feature behind voice and video calls and peer-to-peer data. To find a working path it sends UDP requests to a STUN server, which replies with the address it saw. If that UDP request doesn’t go through your proxy, the STUN server sees your home connection’s public IP, and any web page can read it. That is a WebRTC leak. Modern browsers hide your local network IP by default, but not the public IP that STUN reports back. For someone in mainland China, the leaked address is usually a mainland IP that doesn’t match the proxy exit.
How WebRTC learns your IPs
WebRTC uses ICE to gather “candidate” addresses and then tests which ones connect. RFC 8445 defines several types; two matter here:
- host: an address on one of your network interfaces, including virtual ones such as a VPN’s. Usually a private IP like
192.168.x.x. - srflx (server reflexive): the address and port a STUN server saw when your device sent it a packet. RFC 8489 describes STUN as a way for an endpoint to learn the IP and port a NAT allocated to it.
Candidates are handed to the page as text lines (RFC 8839) ending in typ host, typ srflx and so on. No camera or microphone permission is needed: WebKit explains that without that access Safari still exposes server-reflexive and TURN candidates.
mDNS hides the local IP, not the public one
Local IPs can be used for tracking, so browsers replace the address in host candidates with a random .local name. The IETF draft describing this (a random UUID plus .local) expired without becoming an RFC, but browsers ship the idea:
- Chrome began rolling it out in Chrome 76 in 2019; the announcement says it applies to all sites except those with camera or microphone permission.
- Firefox has
media.peerconnection.ice.obfuscate_host_addresseson by default, and its source skips the obfuscation while a page is capturing or holds camera or microphone permission. - Safari withholds host candidates until the page is granted camera or microphone access.
The same draft is explicit that a server-reflexive candidate is still generated, and it carries a real IP address. mDNS does nothing for the public address STUN sees.
Why it leaks with a proxy on
RFC 8828, the IETF’s WebRTC IP-handling requirements, lists three exposures: a split-tunnel VPN lets WebRTC find both the VPN address and the ISP address; private addresses behind a NAT can be learned; and behind a proxy with direct internet access allowed, STUN checks bypass the proxy and reveal the client’s public IP. It also notes that all HTTP proxies and most SOCKS proxies don’t support UDP.
In terms of a typical proxy app:
- System proxy mode: the app registers itself as the OS HTTP / SOCKS proxy, and page requests go through it. WebRTC’s UDP follows the routing table straight out of your home connection, so STUN sees your real public IP.
- TUN mode (virtual adapter / enhanced mode): the app creates a virtual network device — the Linux kernel docs describe a TUN device as one that passes packets to and from a user-space program — so UDP reaches the app too. What happens next depends on whether the line can forward UDP and on your routing rules; requests to STUN servers inside China may match a “direct” rule.
Any page can read srflx addresses with a few lines of JavaScript. Whether ChatGPT, Claude or Gemini do, and how they would use it, isn’t public. Still, page traffic from an overseas exit next to a WebRTC address in mainland China is a pair of signals that don’t agree.
How IP Judge tests for it
The check runs on the home page and on the Claude, ChatGPT and Muse pages, in the WebRTC row of “Browser and connection checks”:
- It opens four WebRTC connections at once, each with a single STUN server: Cloudflare (
stun.cloudflare.com:3478), Google (stun.l.google.com:19302), and two in China, Xiaomi (stun.miwifi.com:3478) and Bilibili (stun.chat.bilibili.com:3478). The Chinese servers are there because routing rules often send them direct; asking only an overseas server can miss the leak. - Each connection creates a data channel and an offer to start candidate gathering, and keeps the first srflx address and the first host address. It stops when gathering completes, or after 4 seconds if a STUN server doesn’t answer.
- Each srflx IP is compared with every exit the page found: the IP that opened the site, the IPs claude.ai and chatgpt.com saw, and the IPv4-only and IPv6-only exits. It compares the IPs themselves, not countries.
- If an overseas STUN server (Cloudflare, Google) returns an IP that matches none of those exits, it’s flagged red as “Leaks another IP”: UDP isn’t going through the proxy, which is typical of system-proxy mode.
- If only the China-based STUN servers (Xiaomi, Bilibili) return another IP, it’s flagged amber as “China STUN goes direct”. The overseas servers see your proxy exit, so UDP is already proxied; your routing rules treat the China-based STUN domains as direct. Only a site that deliberately asks a China-based STUN server can read that IP, so it costs half the points.
- Either way, the page looks up the IP’s country and network, adds it to “Who sees which of your IPs”, and lists the matching fix under “How to fix”.
- All srflx IPs match an exit: “Consistent”. No STUN server answered: “No leak”. WebRTC missing or disabled: “WebRTC is unsupported or disabled”, also counted as no leak.
- A
.localhost address is shown as hidden by the browser (normal). A real local IP is displayed as a note and doesn’t count as a leak.
In the Claude score, a WebRTC leak costs 12 of the 20 points in the Leaks section (6 if only China-based STUN servers leak); in the Muse sign-up score it costs 10 of 15 (5). These are IP Judge’s own weights, not published platform rules — see the Method page.
What each browser offers
Chrome and Edge
- Google publishes an official extension, WebRTC Network Limiter (developer: Google Ireland, Ltd.; still listed as of this writing, last updated October 2023). By default it stops WebRTC from using private IPs and public IPs on interfaces that don’t carry web traffic. With a system proxy you also need its option to disable non-proxied UDP, which is off by default and set on the extension’s Options page. The store listing warns that since most proxies don’t handle UDP, this effectively turns UDP off, and calls may lag or lose quality.
- On managed machines, Chrome’s WebRtcIPHandling policy (Chrome 91+) set to
disable_non_proxied_udponly uses UDP when a configured proxy supports it; WebRtcIPHandlingUrl (Chrome 133+) sets it per site. Edge’s equivalent is WebRtcLocalhostIpHandling (Edge 77+ on Windows and macOS), whereDisableNonProxiedUdpmeans TCP unless the proxy supports UDP; it needs a browser restart. - If the check shows a real local IP in Chrome, the WebRtcLocalIpsAllowedUrls policy may list the site, or
chrome://flags/#enable-webrtc-hide-local-ips-with-mdnsmay be disabled.
Firefox
The controls live in about:config: type about:config in the address bar, accept the warning, search for the preference and double-click a true/false value to toggle it (Mozilla’s guide). A 2025 Mozilla Connect idea asking for a WebRTC toggle in Settings is still marked “New idea”.
media.peerconnection.ice.default_address_onlylimits candidates to the default-route interface;media.peerconnection.ice.no_hostremoves local addresses from candidates (Mozilla wiki).- Also set
media.peerconnection.ice.proxy_only_if_behind_proxyto true. In Firefox’s source, the extension API’sdisable_non_proxied_udpis exactly these three set to true. media.peerconnection.enabledset to false turns off RTCPeerConnection entirely (MDN); sites that need in-browser calls stop working.
Safari
Per WebKit, Safari doesn’t give ordinary pages your local addresses but does give them srflx candidates, so it leaks the public IP in system proxy mode just the same. We found no Apple documentation of a user-facing WebRTC switch. The developer setting “Disable ICE Candidate Restrictions” turns off host-candidate filtering according to WebKit; it is for testing, so leave it off. Safari users mostly rely on the network side, below.
Proxy apps: system proxy vs TUN mode
The goal is for WebRTC’s UDP to leave through the same exit as your page traffic, or not leave at all.
- In system proxy mode STUN always goes direct. Either switch to TUN mode, or disable non-proxied UDP in the browser as above.
- In TUN mode, check that your line forwards UDP. If it doesn’t, make sure UDP is dropped rather than sent direct.
- Check that your rules don’t send STUN servers — especially ones in China — direct.
- Re-run the check on the home page. All four STUN rows should show your exit IP or “no response”.
For how to read the IP each AI site sees, see Which IP do ChatGPT and Claude actually see? The DNS side of the same problem is covered in DNS leaks.
FAQ
The WebRTC IP is in the same country as my exit. Is that still a leak?
IP Judge compares IPs, so any address that matches none of your exits is flagged, even in the same country. Look at the network the page shows: if it’s your home ISP, your real IP is leaking; if it’s another proxy line, your UDP is taking a different exit, which is worth making consistent too.
My local address shows as a long .local name. Is something wrong?
No. The browser replaced your local IP with an mDNS name, so pages can’t see your real LAN address.
Does granting a site camera or microphone access change anything?
Yes. Chrome, Firefox and Safari all relax host-candidate protection for sites with that permission, which is why a video-call site can see your local IP.
Isn’t it easier to just turn WebRTC off?
It is, but in-browser voice and video calls stop working, and the check will show WebRTC as unsupported or disabled. Routing UDP through the proxy is the cleaner fix; restrict the browser when you can’t.
Which kind of IP do you have?
Check my IP for free