WebRTC STUN Leaks: Bypassing VPN Split-Tunneling
The STUN Paradox
WebRTC (Web Real-Time Communication) enables real-time peer-to-peer media inside the browser. To establish connections across NAT layers, the browser utilizes the STUN (Session Traversal Utilities for NAT) protocol over UDP.
When an application requests an ICE candidate, the browser sends a raw UDP datagram to a public STUN server (e.g., stun.l.google.com:19302). The danger stems from OS-level socket routing: many commercial VPN clients only hook the system TCP stack or the browser's HTTP proxy interface.
Because WebRTC generates UDP packets at the kernel level, the socket frequently binds directly to the physical interface (eth0 or wlan0) instead of the virtual tunnel (tun0), leaking the baremetal residential IP to the STUN server.
ICE Candidate Types
During the gathering phase, the JavaScript execution context receives three specific IP vectors:
- Host: The private LAN IP assigned by the local DHCP router (e.g.,
192.168.1.50). - Server Reflexive: The public IP seen by the STUN server. If the UDP socket bypassed the VPN, this is the true residential IP address.
- Relayed: The fallback IP address of an intermediate TURN server.
Policy Mitigation
To prevent this leak without completely disabling WebRTC runtime objects, the engine must be constrained via the ICE transport policy:
// Enforced runtime constraint
RTCConfiguration.iceTransportPolicy = "relay";
Setting the policy strictly to relay forces all media packets through the encrypted TCP/TLS proxy stack, neutralizing the UDP direct-binding vulnerability instantly.