What Is WebRTC Fingerprinting? β Definition and How It Works
Learn how WebRTC leaks local and public IP addresses through ICE candidates, and why it defeats proxy configuration.
WebRTC fingerprinting exploits the fact that WebRTC's connection setup discovers and exposes network addresses β including ones an HTTP proxy was supposed to hide.
1. Why WebRTC Knows Your Address
WebRTC establishes peer-to-peer connections, which requires each peer to discover how it can be reached. That discovery process β ICE, using STUN servers β enumerates candidate addresses: local network addresses, and the public address as seen by an external server.
The critical detail: this happens over UDP, outside the HTTP stack. An HTTP or SOCKS proxy configured for the browser's page loads does not necessarily carry WebRTC traffic, so the address discovered can be the machine's real one.
2. The Leak
const pc = new RTCPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]});
pc.onicecandidate = e => { if (e.candidate) console.log(e.candidate.candidate); };
pc.createDataChannel("");
pc.createOffer().then(o => pc.setLocalDescription(o));
Candidate strings contain addresses. A srflx (server-reflexive) candidate carries the public address as STUN saw it β and if that differs from the address your HTTP requests appear to come from, the mismatch is the tell.
3. Why This Matters for Proxied Automation
A browser routed through a proxy presents the proxy's address over HTTP. If WebRTC then reports a different public address, a site can observe both and conclude that a proxy is in use.
That is a much stronger signal than most fingerprinting, because it is not a probabilistic inference β it is two contradictory addresses for one session.
| Observation | Meaning |
|---|---|
| HTTP IP and WebRTC IP match | Consistent |
| They differ | A proxy or VPN is in play |
| WebRTC blocked entirely | Also unusual, and itself a signal |
| Only local candidates appear | Partial mitigation, commonly seen |
4. Local Addresses Leak Too
Beyond the public address, host candidates expose private network addresses β 192.168.x.x, 10.x.x.x β and historically mDNS hostnames. That reveals internal network structure and, in aggregate, contributes to device identification.
Modern browsers mitigate this by replacing local addresses with randomised mDNS identifiers, which reduces the leak without eliminating the signal that WebRTC is available.
5. Mitigations, and Their Own Tells
Disable WebRTC entirely. Effective against the leak, and detectable: a current Chrome build with RTCPeerConnection missing is itself anomalous.
Force WebRTC through the proxy. The correct fix where supported, since the discovered address then matches. Requires the proxy to handle UDP, which many HTTP proxies do not.
Policy restriction to relay-only or disable non-proxied UDP. Chromium exposes preferences for this, and it is the practical middle ground.
Accept the leak, and make the addresses agree by running the browser in a network whose egress is the intended address β no proxy, just the right location. Frequently the cleanest answer.
The general lesson: each mitigation trades one signal for another, and the only configuration with no tell is one where the addresses genuinely match.
6. Testing Your Own Setup
Worth doing explicitly, because the failure is invisible otherwise:
page.goto("about:blank")
result = page.evaluate("""() => new Promise(res => {
const out = [];
const pc = new RTCPeerConnection({iceServers:[{urls:'stun:stun.l.google.com:19302'}]});
pc.onicecandidate = e => e.candidate ? out.push(e.candidate.candidate) : res(out);
pc.createDataChannel('x');
pc.createOffer().then(o => pc.setLocalDescription(o));
setTimeout(() => res(out), 4000);
})""")
Compare any address in the output against the address your HTTP requests present. If they differ, the leak is live.
7. Beyond Addresses
WebRTC also exposes codec and capability information via RTCRtpReceiver.getCapabilities(), and the supported codec list varies by browser build and platform. That contributes entropy independently of any address leak, so even a fully proxied WebRTC stack still surfaces device characteristics.
8. Summary
WebRTC fingerprinting uses ICE candidate discovery to obtain local and public IP addresses over UDP, outside the HTTP path a proxy controls.
The decisive signal is a WebRTC-reported public address that contradicts the HTTP-visible one, which demonstrates a proxy rather than merely suggesting it β so route WebRTC through the same egress, restrict non-proxied UDP, or run from a network whose real egress is the intended one, and test explicitly because the leak is otherwise invisible.