WebRTC IP Leaks: Protocol Architecture, ICE Candidate Snooping & De-Anonymization Defense
WebRTC (Web Real-Time Communication) revolutionized the web by enabling peer-to-peer audio, video, and data transmission directly between client browsers without intermediaries. However, its core mechanism—Interactive Connectivity Establishment (ICE) combined with STUN (Session Traversal Utilities for NAT)—bypasses conventional operating-system-level VPN routing tables. This deep dive breaks down the underlying network mechanics, examines packet captures, and delivers enterprise-grade defense strategies.
1. Anatomy of the WebRTC Peer Connection Handshake
When two browsers communicate via WebRTC, they must discover how to establish a direct network path through routers, firewalls, and Symmetric or Cone NATs. To achieve this, WebRTC utilizes the ICE protocol (RFC 8445), which coordinates discovery through STUN (RFC 8489) and TURN (RFC 8656) servers.
The connection pipeline follows three distinct phases:
- SDP Offer Generation: The calling client creates an
RTCPeerConnectionobject. The browser generates a Session Description Protocol (SDP) blob describing supported media codecs, encryption fingerprints (DTLS-SRTP), and network candidate requirements. - ICE Candidate Gathering: The browser queries every available local network adapter (Ethernet, Wi-Fi, virtual TAP/TUN interfaces) and dispatches UDP binding requests to public STUN servers.
- Signaling & Hole Punching: Candidate addresses are transmitted out-of-band via WebSockets or HTTPS to the remote peer, which begins connectivity checks to find the lowest-latency path.
During candidate gathering, the browser does not restrict binding queries to the default system routing interface. Instead, it dispatches UDP STUN packets across all physical and virtual network interfaces in parallel. Even if your default gateway is redirected through an encrypted WireGuard or OpenVPN tunnel, the browser queries your local Wi-Fi or LTE adapter directly, immediately harvesting your true public ISP IP address.
2. Deconstructing ICE Candidate Types
In any WebRTC candidate exchange, three primary candidate formats are exposed:
| Candidate Type | Transport Protocol | Exposed Information | Privacy Impact |
|---|---|---|---|
| Host (host) | Direct UDP/TCP | Internal private LAN IP (e.g., 192.168.1.45 or 10.0.0.12) |
Reveals internal network subnet topology and device clustering. |
| Server Reflexive (srflx) | STUN UDP Binding | True public WAN IP address and external NAT port mapping | Critical Leak: Discloses true ISP, geographic city/GPS, and identity. |
| Relay (relay) | TURN Tunneling | TURN server IP address and allocated relay port | Zero leak; traffic is mediated securely via third-party relay. |
3. Examining the JavaScript STUN Harvest Vector
A malicious tracker does not require elevated permissions, browser extensions, or user prompts (such as camera or microphone permission) to harvest STUN candidates. The following standard JavaScript snippet demonstrates how any third-party script embedded on an ad network can silently harvest your network endpoints:
// Standard WebRTC STUN Snooping Vector (Passive Execution)
const rtc = new RTCPeerConnection({
iceServers: [
{ urls: "stun:stun.l.google.com:19302" },
{ urls: "stun:stun1.l.google.com:19302" }
]
});
rtc.createDataChannel("leak-probe");
rtc.onicecandidate = (event) => {
if (!event || !event.candidate) return;
const candidate = event.candidate.candidate;
console.log("[Discovered Endpoint]:", candidate);
// Extract IPv4/IPv6 addresses via regex
const ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/i;
const match = candidate.match(ipRegex);
if (match) {
const leakedIP = match[1];
// Exfiltrate to analytics endpoint silently
navigator.sendBeacon("/telemetry/collector", JSON.stringify({ ip: leakedIP }));
}
};
rtc.createOffer()
.then(offer => rtc.setLocalDescription(offer))
.catch(err => console.error("WebRTC Probe Blocked:", err));
4. Why mDNS Obfuscation Is Incomplete
In response to widespread WebRTC privacy complaints, Google, Mozilla, and Apple implemented RFC 8828 (mDNS ICE Candidate Obfuscation). Under mDNS, local host candidates like 192.168.1.105 are replaced with randomized UUIDs (e.g., 5c8b671a-2fa9-4a92-9382-7cfa21a6b0c1.local).
While mDNS successfully shields private subnet enumeration from casual inspection, it provides zero protection against Server Reflexive (srflx) public IP exposure. The moment an external STUN server is queried, the response packet carries the true public WAN IP of the router, bypassing mDNS entirely.
5. Complete Cross-Platform Remediation Matrix
To achieve absolute immunity from WebRTC deanonymization, implement these platform-specific hardening rules:
Mozilla Firefox (Native System Flag)
Firefox remains the single major browser supporting native, plugin-free deactivation of the WebRTC subsystem:
- Navigate to
about:configand accept the risk warning. - Search for
media.peerconnection.enabled. - Toggle the preference from
truetofalse. - Verify that
media.navigator.enabledis also set tofalse.
Chromium, Brave & Google Chrome (Policy Enforcement)
Chromium-based browsers do not offer a native kill-switch because WebRTC powers fundamental browser services. However, you can enforce restrictive routing policies:
- Brave Browser: Open
brave://settings/shields→ set WebRTC IP Handling Policy to Disable Non-Proxied UDP. - Enterprise GPO / Managed Policy: Deploy the
WebRtcIPHandlingPolicyJSON policy:{ "WebRtcIPHandlingPolicy": "disable_non_proxied_udp" } - Extension Hardening: Install uBlock Origin → Dashboard → Settings → check "Prevent WebRTC from leaking local IP addresses".
Linux OS-Level Firewall Rule (iptables / nftables)
For high-security Linux workstations, you can drop non-tunneled UDP STUN traffic entirely by blocking standard STUN port ranges (3478, 5349) outside the tun0 or wg0 interface:
# Drop outbound STUN requests leaking via physical eth0/wlan0
iptables -A OUTPUT -o eth0 -p udp -m multiport --dports 3478,5349 -j DROP
iptables -A OUTPUT -o wlan0 -p udp -m multiport --dports 3478,5349 -j DROP
Frequently Asked Questions & Technical Clarifications
Does incognito or private browsing mode prevent WebRTC leaks?
No. Private browsing mode and Incognito mode isolate cookies, cache, and session history upon window closure. However, the networking subsystem and ICE candidate gathering pipelines execute identically in incognito mode, exposing your real IP address to STUN queries.
Why doesn't my commercial VPN's Kill Switch block WebRTC?
Standard VPN kill switches monitor the state of the VPN virtual network adapter (TAP/TUN) and block traffic if the tunnel disconnects. WebRTC leaks happen while the VPN is active because your browser binds directly to raw hardware network sockets on your Wi-Fi card, evading the routing table entirely.
Does disabling WebRTC break video conferencing websites?
Yes. Disabling WebRTC will break in-browser Google Meet, Discord Voice Web, Zoom Web Client, and Microsoft Teams browser audio. If you require these services, configure your policy to 'Disable Non-Proxied UDP' rather than completely disabling peer connections.
Run our browser-based STUN leak detection, DNS resolver tracing, and cryptographic hashing tools with zero server-side logging.