A WebRTC leak happens when a page asks the browser's real-time communication engine for connection candidates and receives your actual public or local IP address, even though your traffic is routed through a VPN or proxy. It occurs because WebRTC discovers addresses through STUN and ICE outside the normal page request path, and it is fixed by restricting or disabling that discovery in the browser.

What WebRTC is for

WebRTC, standardised by the W3C and the IETF (RFC 8825 gives the overview), lets two browsers exchange audio, video and data directly, without a server relaying every packet. Video calls in a browser tab, browser-based screen sharing and some peer-to-peer file transfer tools are built on it. To connect two machines that are each behind a home router, it has to work out which addresses could reach each of them. That discovery step is where the privacy problem lives.

The discovery protocol is ICE, Interactive Connectivity Establishment (RFC 8445). The browser collects candidates: its own interface addresses (host candidates), the public address a STUN server sees the request arriving from (server-reflexive candidates), and, if configured, a relay address on a TURN server. The candidates are handed to the page's JavaScript so it can send them to the other party. A page that never intends to make a call can create a connection object, ask for candidates and simply read the addresses out.

const pc = new RTCPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]});
pc.createDataChannel("");
pc.onicecandidate = e => { if (e.candidate) console.log(e.candidate.candidate); };
pc.createOffer().then(o => pc.setLocalDescription(o));

// typical output on an unprotected browser:
// candidate:1 1 udp 2122260223 192.168.1.23 51234 typ host ...
// candidate:2 1 udp 1686052607 203.0.113.45 51234 typ srflx raddr 192.168.1.23 ...

Two things are notable about that snippet. It needs no permission prompt, because no camera or microphone is involved. And the srflx line contains the address the STUN server saw, which is your public address as reached by the browser's UDP socket, not necessarily the address your VPN presents to websites.

Why a VPN does not automatically stop it

A VPN client's job is to route all traffic through the tunnel. If it does that completely, the STUN packet also goes through the tunnel and the server-reflexive candidate is the VPN's exit address, which is fine. Leaks happen when some traffic escapes the tunnel:

  • IPv6. Many VPN clients tunnel IPv4 and leave IPv6 untouched or improperly blocked. The browser gathers an IPv6 host candidate that is your real, globally routable address.
  • Split tunnelling. If the browser or UDP traffic is excluded from the tunnel, STUN goes out directly.
  • Proxies rather than VPNs. An HTTP or SOCKS proxy configured in the browser handles HTTP requests; WebRTC's UDP sockets do not use it unless the browser is told to restrict WebRTC to proxied paths.
  • Kill switch gaps. During a reconnect, or before the client has established its routes, candidates gathered in that window carry the real address.

The public-address leak is the one that matters. The local address leak (a 192.168.x.x or 10.x.x.x host candidate) was the original 2015 discovery and it has largely been closed: Chrome, Firefox and Safari now replace host candidates with random mDNS names such as a1b2c3d4-….local that only resolve on the local network. A page can no longer learn your LAN address without a permission grant. Our WebRTC IP leak check therefore concentrates on comparing the public addresses WebRTC returns with the address your connection presents, and the wider picture of what an address reveals is in what your IP address reveals.

How to test for a leak

  1. Connect your VPN and confirm it is active.
  2. Open the WebRTC and IP leak test. It reports the address the connection arrived from and every candidate WebRTC exposed.
  3. Compare. If all WebRTC candidates are mDNS names or match the VPN exit, there is no leak. If a public IPv4 or IPv6 address appears that is not the VPN's, you have one.
  4. Repeat in a private window with extensions off, because a leak-blocking extension can mask the browser's real behaviour.
  5. Repeat on each browser you use; the fix is per browser, not per machine.
If the test shows an IPv6 address you do not recognise while the IPv4 address matches the VPN, the browser is fine and the VPN client is the problem. Enable its IPv6 leak protection or disable IPv6 on the interface.

The fix in each browser

BrowserWhereSettingEffect
Firefoxabout:configmedia.peerconnection.enabled = falseDisables WebRTC entirely; browser video calls stop working
Firefox (milder)about:configmedia.peerconnection.ice.default_address_only = true, and media.peerconnection.ice.proxy_only_if_behind_proxy = trueUses only the default route's address and honours a configured proxy; calls keep working
ChromeExtensionGoogle's WebRTC Network Limiter, mode "Use my proxy server (if present)" or "Disable non-proxied UDP"Restricts candidates to the default public interface or proxied paths
Chrome (managed)Enterprise policyWebRtcIPHandling = default_public_interface_only or disable_non_proxied_udpSame restriction, enforced by policy
EdgeExtension or policySame options as Chrome; the Network Limiter extension installs from the Chrome Web StoreSame
SafariNoneNo user-facing control; mDNS candidates are on by defaultLocal addresses are hidden; public address follows the system route

A few notes on those choices. Disabling WebRTC in Firefox is the only complete fix, and the cost is real: any site that uses WebRTC for calls or screen sharing will fail. The milder Firefox prefs and the Chrome extension's "default public interface only" mode are the right answer for most people, because they keep calls working while ensuring the browser only ever offers the address of the interface it would use for ordinary traffic, which under a properly configured VPN is the tunnel. In Chrome, set the extension to the most restrictive mode your video calls tolerate; "Disable non-proxied UDP" forces TURN relays and breaks some calls.

Safari's lack of a control is less alarming than it sounds. Safari restricts ICE candidates and uses mDNS by default; the remaining exposure is the public address, which on macOS and iOS follows the system's routing table, so a system-wide VPN that tunnels IPv6 as well as IPv4 leaves nothing for WebRTC to reveal.

Reading a leak test result

A leak test presents two lists, and the whole judgement is a comparison between them. Here is what a genuine leak looks like on a laptop with a VPN client that tunnels IPv4 but not IPv6:

Connection address (what websites see):   185.220.101.7     (VPN exit, Netherlands)
WebRTC candidates:
  typ host   f3a9c2d1-7e4b-4c8a-9d21-0b6e5a8f1c3d.local    (mDNS, fine)
  typ srflx  185.220.101.7                                 (VPN exit, fine)
  typ host   2a02:8071:1234:5678:a1b2:c3d4:e5f6:0789       (real IPv6, LEAK)

The first candidate is an mDNS name, which is the browser doing its job. The second is the VPN's own address, which is what a working tunnel should produce. The third is a globally routable IPv6 address belonging to the home ISP, and it identifies the household as precisely as an IPv4 address would. A site running the snippet earlier in this guide would have it within a second of the page loading. The fix in this case is in the VPN client, not the browser: enable its IPv6 protection or disable IPv6 on the adapter, then re-test. If the VPN cannot be fixed, the browser-side restrictions are the fallback.

The opposite result, a test that shows no public candidates at all, is not automatically good either. It usually means an extension or preference has disabled WebRTC, which is fine if you chose it and worth investigating if you did not, because it also means browser video calls will fail without an obvious reason. A third pattern is a relay-only result, where the only public candidate belongs to a TURN server: that is what the strictest Chrome extension mode produces, and it means the browser is refusing to expose any direct route at all.

Whether you should disable WebRTC at all

Take a position on this rather than defaulting to the maximum. If you do not use a VPN or proxy, WebRTC reveals an address every website already sees in your ordinary requests, so disabling it gains nothing and breaks video calls. If you use a VPN specifically to hide your address from the sites you visit, a leak completely defeats that purpose and the restriction is worth its cost. If you rely on a browser proxy, use the proxy-only options, because a browser proxy was never covering UDP in the first place. The comparison of what each tool hides is in VPN vs proxy vs Tor; Tor Browser disables WebRTC outright for exactly this reason.

There is also a fingerprinting angle. The set of candidates a browser returns, and whether it returns any, is one more signal for the scripts described in the browser security hub. Disabling WebRTC makes you unusual; restricting it to the default interface does not. That is another reason the milder settings are the better default. Once fixed, re-run the test and then the rest of the checklist in is my browser secure; the other per-browser toggles are catalogued in browser security settings.