Even with a VPN active, WebRTC's ICE and STUN candidate gathering can expose your real public IP. How the leak works, how to test it, and how to fix it.
A WebRTC leak happens when your browser's real-time communication feature reveals your true IP address — including your real public IP — even while a VPN is active. To stop it, you either disable WebRTC, restrict it to use only your VPN's network interface, or run a VPN that explicitly blocks WebRTC leaks. Below we explain exactly how the leak works, how to test for it, and the safest way to fix it without breaking video calls.
What WebRTC Is and Why Browsers Ship It
WebRTC (Web Real-Time Communication) is a browser technology that lets web pages exchange audio, video, and arbitrary data directly between two devices — peer-to-peer — without a plugin. It powers in-browser video conferencing, voice calls, screen sharing, and file transfer on sites like Google Meet, Discord, and countless support-chat widgets.
Because WebRTC connects two peers directly rather than routing everything through a central server, each peer needs to learn how the other can be reached on the network. That discovery process is the root of the leak. WebRTC is not malware and it is not a bug — it is doing exactly what it was designed to do. The problem is that the same machinery that finds the best network path for your video call can also hand your real IP address to any script on the page.
The ICE Process: STUN, TURN, and Candidate Gathering
To set up a direct connection, WebRTC uses a framework called ICE (Interactive Connectivity Establishment), standardized in RFC 8445. ICE collects every possible way the two peers might reach each other and ranks them by the priority formula the RFC defines — host candidates are tried first, then server-reflexive, then relay — so the browser always attempts the most direct (and most revealing) path before falling back to a relay. Each of these is called a candidate.
There are three main candidate types:
- Host candidates — your device's local network addresses (e.g.
192.168.x.xor10.x.x.xLAN IPs, and sometimes IPv6 addresses). - Server-reflexive candidates — your public IP as seen from the outside, discovered by asking a STUN server. A STUN (Session Traversal Utilities for NAT) server simply replies, "this is the public IP and port I see you coming from." This is the candidate that can expose your real IP.
- Relay candidates — a fallback that routes media through a TURN server when a direct connection is impossible. TURN servers relay traffic, so they don't reveal a new IP, but they cost bandwidth and are used only as a last resort.
The danger is that ICE gathers candidates eagerly and silently. A web page can create a connection, never actually call anyone, and still read out the candidates your browser collected — including the STUN-discovered public IP.
Why a VPN Doesn't Always Save You
Here is the part that surprises most VPN users. When you connect a VPN, your normal web traffic is tunneled through the VPN's interface, so whatismyip shows the VPN's address. But WebRTC's STUN request is a separate UDP flow. Depending on your operating system's routing rules, your VPN's split-tunnel settings, and the browser's interface-binding behavior, that STUN request can travel over your real network interface instead of the tunnel. The STUN server then reports your real public IP, and the page reads it — completely bypassing the VPN.
In other words, the VPN protects your HTTP traffic while WebRTC quietly leaks the IP you were trying to hide. If you want to confirm whether your VPN actually masks your address, run BrowserInsight's VPN/proxy check and IP intelligence tools to see what the outside world really observes.
mDNS .local Obfuscation and Its Limits
Modern Chromium browsers (Chrome, Edge) and Firefox added a mitigation for local IP exposure: instead of exposing a raw 192.168.x.x host candidate, they replace it with a randomized mDNS hostname that looks like a1b2c3d4-....local. This .local address is meaningless to a remote script, so your LAN topology stays private while the connection still works on your local network.
The standard that governs this area is RFC 8828, "WebRTC IP Address Handling Requirements." It does not mandate the .local trick itself — instead it defines four IP-handling modes and how much of your network each one may reveal: Mode 1 enumerates every address, Mode 2 uses the default route plus its associated local addresses, Mode 3 uses the default route only, and Mode 4 forces traffic through a proxy. The randomized mDNS name is the technique browsers converged on to satisfy the strict end of that scale for host candidates: the browser publishes a random name on the local link and hands out the name instead of the address, so the LAN IP itself never leaves your machine.
It is a genuine improvement, but it has two important limits:
- It only conceals host (local) candidates. A server-reflexive candidate is, by definition, a public address — it is what a STUN server on the open internet saw your packet arrive from, so there is no local name to substitute for it. Your real public IP is not hidden by mDNS, and that is the leak that matters most for VPN users.
- It depends on browser and platform support. Older browsers, some embedded webviews, and certain configurations may still expose raw local IPs.
So mDNS reduces fingerprinting via your LAN address, but it is not a defense against public-IP leakage.
Where RFC 8828 does help VPN users is Mode 3. "Default route only" means WebRTC may use nothing but the interface your operating system already uses for ordinary traffic — and with a VPN up, that interface is the tunnel. The STUN request then leaves through the tunnel, and the server-reflexive candidate reports the VPN's address instead of yours. That is exactly what the browser controls in the next section do under the hood.
How the Leak Looks in Code
You don't need a special tool to trigger candidate gathering. Any page can do it with the standard RTCPeerConnection interface, defined in the W3C WebRTC specification, using nothing more than a few lines of JavaScript. The snippet below creates a peer connection, points it at a public STUN server, and prints every candidate the browser discovers:
// Reveal the IP candidates WebRTC gathers
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
// Force the browser to start gathering ICE candidates
pc.createDataChannel('leak-test');
pc.onicecandidate = (event) => {
if (!event.candidate) return; // gathering finished
const candidate = event.candidate.candidate;
// ICE candidate strings contain the IP in field 5
const ipMatch = candidate.match(
/([0-9]{1,3}(\.[0-9]{1,3}){3})|([a-f0-9]{1,4}(:[a-f0-9]{0,4}){2,7})/i
);
if (ipMatch) {
console.log('Candidate type:', event.candidate.type);
console.log('Exposed address:', ipMatch[0]);
}
};
pc.createOffer().then((offer) => pc.setLocalDescription(offer));
If event.candidate.type is srflx (server-reflexive) and the printed address is your real public IP rather than your VPN's, you have a WebRTC leak.
How to Test for a WebRTC Leak
Testing takes about a minute:
- Connect your VPN and confirm it's active.
- Note the public IP your VPN claims to give you — BrowserInsight's IP intelligence page shows it.
- Run BrowserInsight's VPN/proxy check. It performs the candidate gathering above in your own browser and reports the WebRTC public IP alongside the IP your HTTP requests actually arrive from, flagging a mismatch as a WebRTC leak. (If you'd rather see it raw, paste the snippet above into your browser console.)
- Compare the addresses WebRTC reveals against your VPN IP.
If WebRTC surfaces an IP that matches your VPN, you're protected. If it surfaces a different public IP — your home or ISP address — that's the leak. A leaked IP only matters to a tracker if it actually pinpoints you, and IP geolocation is less precise than many assume — though usually accurate enough to reveal your city and ISP. For a cross-check on what your connection exposes beyond WebRTC, this pairs well with a DNS leak test, since DNS and WebRTC leaks often share the same root cause: traffic escaping the tunnel.
Per-Browser Mitigation
There is no single switch that fixes WebRTC everywhere, because each browser handles it differently. The table below summarizes practical options.
| Browser / Platform | How to mitigate | Tradeoff |
|---|---|---|
| Chrome / Edge (desktop) | No built-in setting page; the IP-handling policy is only reachable through an extension. Google's own WebRTC Network Limiter sets it to the default-public-interface option — RFC 8828 Mode 3 — so candidates are gathered on the tunnel only | Extension can break some video apps |
| Firefox | Open about:config, set media.peerconnection.enabled to false to disable WebRTC entirely | Fully breaks WebRTC video/voice calls |
| Safari (macOS/iOS) | No user-facing off switch in stable builds. On iOS this is not a browser choice at all — every iOS browser runs on WebKit, so switching browsers changes nothing; use a system-level VPN that blocks WebRTC leaks | Little user control |
| Brave | Built-in setting: change WebRTC IP handling policy to "Disable non-proxied UDP" under privacy settings — the strictest option, equivalent to RFC 8828's Mode 4 | May affect peer-to-peer apps |
| Mobile (Android/iOS) | Use a browser with WebRTC controls (Brave, Firefox) or a VPN app that blocks WebRTC at the network layer | App-level VPN is the most reliable mobile fix |
The cleanest fix for most VPN users is not a browser flag at all — it's choosing a VPN whose desktop and mobile apps explicitly advertise WebRTC leak protection and enforce it at the OS network layer, so the STUN request can never escape the tunnel.
Disabling WebRTC vs. Restricting It
Fully disabling WebRTC (the Firefox media.peerconnection.enabled route) guarantees no leak, but it breaks every in-browser video call, voice chat, and screen share. For most people that's too aggressive.
A better balance is to restrict WebRTC so it only uses your VPN's interface — which is exactly what a leak-prevention extension or a WebRTC-aware VPN does. You keep working video calls while closing the public-IP leak. Reserve a full disable for a dedicated hardened browser profile where you never make calls.
Frequently Asked Questions
Does using a VPN stop WebRTC leaks automatically?
Not always. A VPN tunnels your normal web traffic, but WebRTC's STUN request can take a separate path over your real network interface depending on routing and split-tunnel settings. Many quality VPNs add explicit WebRTC leak protection, but you should test rather than assume.
Will disabling WebRTC break websites?
It breaks features that use WebRTC — browser-based video conferencing, voice calls, screen sharing, and some peer-to-peer file transfers. Ordinary browsing, streaming, and most sites are unaffected. If you rely on video calls, restrict WebRTC instead of disabling it.
Does mDNS .local obfuscation make me safe?
It hides your local LAN IP, which is good for reducing fingerprinting, but it does not hide the public IP that STUN discovers. The public-IP leak — the one that matters for VPN users — is unaffected by mDNS.
How do I know if my VPN actually hides my IP?
Compare the IP your VPN claims against what services actually see. BrowserInsight's VPN/proxy check and IP intelligence show the address and network details the outside world observes, which makes a hidden leak easy to spot.
Conclusion
WebRTC is a useful technology that browsers correctly ship by default, but its candidate-gathering process can reveal your real public IP even behind a VPN. The fix is not to fear WebRTC — it's to understand the ICE/STUN mechanism, test your own setup, and apply the right level of mitigation: restrict WebRTC to the tunnel for everyday use, or disable it entirely in a hardened profile. Test first, then choose the tradeoff that fits how you use the web.
Recommended Reading:


