WebRTC Leaks: How They Expose Your Real IP and How to Test

Key takeaways

  • WebRTC leaks because it is working correctly. Peer-to-peer connection setup is designed to enumerate every address a machine has, including ones your proxy never sees.
  • It uses UDP and its own signalling path. A proxy that only relays TCP has nothing to do with a STUN query, so the query goes out over your normal route with your real IP.
  • The damaging result is not the local 192.168.x.x address — it is a public IP in the candidate list that disagrees with your exit IP. That mismatch says "proxy" on its own.
  • Disabling WebRTC is itself a fingerprint. Ordinary Chrome has it, uses it, and answers when probed. A browser claiming to be Chrome with WebRTC missing is an anomaly nobody's grandmother produces.
  • The correct setting in an anti-detect browser is replace / altered: WebRTC stays present and functional, but the public candidate it reports is rewritten to match the proxy's exit IP.
  • UDP crosses a proxy at all only when the proxy implements SOCKS5 UDP ASSOCIATE. Many providers implement CONNECT and nothing else, so every UDP flow either fails or escapes the tunnel.
  • Test inside the profile you actually work in, and compare three numbers: your exit IP, the public candidate WebRTC reports, and the local addresses it exposes.

A WebRTC leak is not a bug. It is a feature doing exactly what it was designed to do, in a context nobody designing it had in mind.

WebRTC exists so two browsers can talk to each other directly — video calls, voice, screen sharing, peer-to-peer data — without relaying every packet through a server. To find the shortest path between two machines it has to know what addresses those machines have. So it asks, thoroughly, and it does not consult your proxy settings before doing so.

The result is a browser that will happily announce addresses your proxy was chosen to conceal, on a path your proxy may never touch. Here is the mechanism, why switching it off is a worse answer than it sounds, and how to test whichever setup you are running now.

What WebRTC is actually doing when it leaks

WebRTC runs a discovery process called ICE before any peer connection is established. ICE gathers candidate addresses — every local interface the machine has, plus the public address a STUN server reports seeing your packets arrive from, and offers the whole list to the other side so the two ends can pick a workable path. Enumeration is the point.

Three kinds of candidate come out of that process, and they leak different things:

Candidate typeWhere it comes fromWhat it reveals
HostThe machine's own network interfacesLocal addresses, e.g. 192.168.x.x, and interface count
Server-reflexiveA STUN server reporting what public IP it sawYour real public IP, if the query left outside the proxy
RelayA TURN server that will forward mediaThe relay's address, not yours

Modern Chromium releases obscure host candidates behind randomised .local hostnames by default, which blunts the local-address disclosure that older articles focus on. That mitigation does nothing for the second row, and the second row is the one that matters.

The damaging leak is a public address that disagrees with your exit IP. A local 192.168.1.14 tells a site you are behind a router, which is true of nearly everyone. A server-reflexive candidate showing a residential broadband address while your HTTP requests arrive from a mobile carrier tells a site something far more specific: that the connection it is talking to and the machine behind it are in different places.

Why the proxy does not catch it

Because WebRTC's discovery does not use the transport your proxy relays. STUN runs over UDP, and most proxies carry TCP only — an HTTP proxy's CONNECT is a TCP tunnel by definition, and a large number of SOCKS5 implementations never implement the UDP command at all. With no route through the tunnel, the browser falls back to the operating system's normal interface.

This surprises people because the browser is otherwise fully proxied. Page loads, XHR, fetch, WebSocket traffic — all of it goes through the tunnel correctly. Then the same browser opens a UDP socket for STUN, the proxy has no mechanism to intercept it, and it goes out of the default route with your real address on it.

It is structurally the same class of problem as a DNS leak: a second path exists alongside the one you configured and tested, and correctness on the tested path says nothing about the other. The difference is that DNS leaks a location, while WebRTC can leak the address itself.

Two aggravating factors are worth knowing:

Why disabling WebRTC is itself a fingerprint

Turning WebRTC off removes the leak and introduces a different signal. Ordinary Chrome ships WebRTC enabled and functional, and a page can check in a few lines by constructing a peer connection and seeing whether candidates arrive. A browser presenting as Chrome that produces none is describing a configuration almost no ordinary user has.

Fingerprinting works on consistency, not on individual values. The question a detection system asks is not "does this browser have WebRTC" but "does everything this browser reports about itself agree". A Chrome user agent, a Chrome TLS handshake, Chrome's rendering behaviour and a missing WebRTC stack do not agree. You have swapped a leak for a rarity.

That trade can still be correct in narrow cases — an automated scraper that never touches a consumer platform does not need to look like a person. But for account work, where the entire goal is to be unremarkable, removing a standard browser capability is moving in the wrong direction. The same reasoning applies to every aggressive privacy toggle: each one that no normal user changes makes you easier to pick out of a crowd, not harder.

Blocking a signal and normalising a signal look identical in a leak test. They look completely different to a fingerprinting script.

The right answer: replace, not disable

Anti-detect browsers solve this by leaving WebRTC present and rewriting what it reports. The API works, a peer connection can be constructed, candidates are produced, and the public candidate is replaced with the proxy's exit IP while local addresses are masked or replaced with plausible private ones. Everything agrees, and nothing is missing.

Vendors label the modes differently, but they reduce to three:

ModeBehaviourWhen it is right
Real / disabled protectionPasses the machine's genuine candidates throughOnly when you are not hiding the machine at all
Disabled / blockedWebRTC API removed or neuteredAutomation that never faces consumer fingerprinting
Replace / alteredAPI intact, public candidate rewritten to the proxy IPThe default for account work

Getting this right is a configuration step, not a purchase. Both the AdsPower and GoLogin setup pages cover where the setting lives in each product, and the important part in both is the same: the replacement address must be the exit IP your traffic actually leaves from. A profile set to "replace" with a stale or wrong address is a leak that looks like a fix.

For a dedicated mobile proxy this is straightforward, because the exit address belongs to you and changes only when you rotate it. On a rotating pool it is harder, because the value the profile is asserting has to track an address that is moving underneath it.

UDP ASSOCIATE: what lets UDP cross a proxy at all

SOCKS5 defines a command called UDP ASSOCIATE that establishes a UDP relay through the proxy alongside the usual TCP path. It is the only standard mechanism by which UDP traffic can traverse a SOCKS5 proxy. If a provider has not implemented it, no configuration on your side will route a UDP packet through the tunnel, because the tunnel does not accept any.

The practical consequences reach beyond WebRTC:

Most proxy providers implement CONNECT and stop, because TCP covers the browsing and scraping workloads that make up nearly all demand. It is a reasonable engineering decision and it is rarely disclosed, which is why the question is worth asking directly rather than inferring from a feature list. The broader TCP-versus-everything-else trade-off is covered in SOCKS5 vs HTTP proxies.

We implement SOCKS5 UDP ASSOCIATE and enable it per device on request rather than globally, because UDP relaying changes the traffic profile of a device and not every customer wants that. Ask any provider the same question in the same form: is UDP ASSOCIATE supported, and is it on for my proxy specifically.

How to test for a WebRTC leak

You are comparing three numbers gathered from the same browser profile: the exit IP the destination sees, the public candidate WebRTC reports, and whatever local addresses appear in the candidate list. A leak is any disagreement between the first two. Test inside the profile you actually work in, not a clean browser.

Step 1 — record the exit IP. Load an IP-echo page in the proxied profile and note the address. Confirm the same value from the command line if you want a second source.

curl -x socks5h://user:pass@your-proxy-host:port https://api.ipify.org

Step 2 — read the WebRTC candidates. Open a WebRTC test page in the same profile. Note the public address it reports and any local addresses listed.

Step 3 — compare. Then interpret:

What you seeWhat it meansWhat to do
Public candidate matches the exit IPReplacement is working, or UDP is genuinely proxiedNothing
Public candidate is your real ISP addressWebRTC is escaping the proxy entirelySet the profile's WebRTC mode to replace
Public candidate matches an old exit IPThe profile is asserting a stale addressRe-sync the profile after each rotation
No candidates at allWebRTC is disabled — a fingerprint in its own rightSwitch to replace unless you specifically want it off
Local addresses exposed as real private IPsHost candidates are not maskedEnable masking, or accept it as low-value information

Re-test after a rotation. This is the failure that catches people out on mobile proxies specifically: the profile was correct when it was configured, the address changed underneath it, and the assertion no longer matches reality. If you are not certain your rotations actually change the address, that is separately testable.

What a clean WebRTC result does and does not prove

It proves that one specific enumeration path is no longer contradicting your network identity. That is worth having, and it is one input among many. WebRTC consistency does not make a profile trustworthy, and it is not the reason an account survives or does not.

Three limits worth being explicit about:

It is a browser-layer fix for a browser-layer problem. Nothing about candidate rewriting changes the reputation of the address you are exiting from. If the underlying IP is scored badly, a perfectly consistent WebRTC result arrives alongside it, and reputation is computed from entirely different inputs.

It does not touch the rest of the fingerprint. Canvas, WebGL, fonts, screen metrics, timezone, language, and TLS handshake characteristics are all still in play, and they matter more in aggregate than any single leak. Twenty profiles that share a fingerprint are one identity with twenty logins.

Behaviour is not addressed at all. Timing, navigation patterns, and per-account rate limits do not care which IP a request arrived from, and no network-layer or browser-layer setting affects them.

The realistic framing is the same one that applies to DNS and to every other consistency check: these are contradictions you remove so that the harder parts of the problem get a fair hearing. Fixing them does not make you invisible, and any provider telling you otherwise is selling something they cannot deliver. Fixing them does mean a detection system has to work at the level where the real decisions are made, instead of dismissing you on a mismatched address it found in the first hundred milliseconds.

Frequently asked questions

What is a WebRTC leak?

It is when a browser's peer-to-peer connection setup reveals addresses that your proxy was supposed to hide. WebRTC gathers candidate addresses — local interfaces and the public address a STUN server reports seeing — so it can find the shortest path to a peer. If that discovery happens outside the proxy path, the addresses it finds are your real ones.

Why does a proxy not stop WebRTC?

Because WebRTC's discovery runs over UDP on its own path, and most proxies only relay TCP. An HTTP proxy speaks CONNECT, which is TCP by definition, and many SOCKS5 implementations never implement the UDP command. With no route through the tunnel, the browser sends STUN traffic over the operating system's normal interface instead.

Should I just disable WebRTC?

Usually no. Ordinary Chrome ships WebRTC enabled, and a page can detect its absence trivially by constructing a peer connection and seeing nothing happen. You have then replaced a leak with a rarity, which on platforms that fingerprint aggressively is not obviously an improvement. Replacing the reported address is the better answer.

What does the replace or altered WebRTC setting actually do?

It leaves the WebRTC API present and working while rewriting the candidates it produces, so the public address reported matches the proxy's exit IP and local addresses are masked or replaced with plausible ones. The browser still behaves like a browser; the addresses simply agree with the rest of your network identity.

What is SOCKS5 UDP ASSOCIATE and why does it matter?

It is the SOCKS5 command that lets a client relay UDP through the proxy rather than only TCP streams. Without it there is no way for STUN, QUIC or any other UDP traffic to traverse the proxy at all — it either fails outright or takes a direct path outside the tunnel. Many providers do not offer it.

How do I test for a WebRTC leak?

Open a WebRTC test page inside the browser profile you actually use with the proxy, and compare the public address it reports against the exit IP the same profile shows on an IP-echo page. If they differ, WebRTC is escaping the proxy. Also check whether local network addresses are listed.

Dedicated mobile proxies, one dashboard

Real 4G/5G devices on US carrier SIMs. Sticky IP per customer, rotation on demand.

See plans