Por qué ocurre siquiera
WebRTC existe para que los navegadores puedan hablar entre sí directamente — videollamadas, voz, datos entre pares — sin pasar todo por un servidor. Las conexiones directas son el objetivo entero, y para montar una tu navegador tiene que averiguar en qué direcciones se le puede alcanzar.
Lo hace preguntándole a un servidor STUN. El navegador manda un paquete UDP a un endpoint STUN público y el servidor responde con la dirección de origen que ha observado. Esa es tu IP pública, devuelta y entregada a JavaScript como candidato ICE.
El detalle crítico: esto pasa por UDP, fuera del camino HTTP. Un proxy HTTP o SOCKS configurado en el navegador se ocupa del tráfico HTTP. El paquete STUN no lo usa. Tus páginas cargan por el proxy, tu descubrimiento WebRTC no, y en ningún sitio se informa de problema alguno.
Eso es lo que hace distinto a este modo de fallo. Un proxy roto produce errores. Una fuga de WebRTC produce silencio.
Qué ve realmente un sitio
El ataque entero es lo bastante corto como para leerlo de una sentada:
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));
Cada línea de candidato contiene una dirección y un tipo. Tres tipos importan:
| Type | Qué contiene | Riesgo |
|---|---|---|
host | Tu dirección de LAN, por ejemplo 192.168.1.42 | Revela la estructura de la red; mDNS lo mitiga |
srflx | Tu IP pública tal como la vio STUN | Esta es la fuga que importa |
relay | La dirección de un servidor TURN | No revela nada sobre ti |
Si la dirección srflx difiere de la dirección desde la que llegan tus peticiones HTTP, le has regalado al sitio una contradicción que no tuvo que buscar: la página cree que estás en Fráncfort y WebRTC dice que estás en Milán.
RTCPeerConnection. La línea host la enmascara mDNS y la línea relay no revela nada. Solo srflx lleva tu dirección pública.mDNS resuelve la mitad pequeña
Chrome trae ofuscación mDNS para direcciones locales desde la versión 76. En vez de 192.168.1.42, los candidatos host aparecen como un UUID aleatorio terminado en .local. Es algo realmente bueno y viene activado por defecto.
También se malinterpreta a menudo. mDNS solo afecta a los candidatos host — tu dirección de LAN. No hace nada con los candidatos srflx, que son los que llevan tu IP pública. Las guías que te dicen que actives chrome://flags/#enable-webrtc-hide-local-ips-with-mdns y des el problema por resuelto describen un arreglo para la mitad menos importante.
Aquí hay también una señal de segundo orden. El nombre de host ofuscado .local es estable durante la sesión de navegación, y el número de candidatos host refleja cuántas interfaces de red tiene la máquina. Un perfil que informa seis interfaces parece una máquina con varios adaptadores VPN — no lo que parece un portátil corriente.
Cuatro maneras de gestionarlo
Los navegadores antidetect suelen ofrecer alguna versión de estas cuatro. No son igual de buenas, y la mejor depende de lo que estés haciendo.
Desactivado del todo
Ni RTCPeerConnection, ni candidatos, ni fuga. Limpio, pero detectable: WebRTC lleva una década siendo estándar en todos los navegadores, y un Chrome sin él es raro. Vale para cuentas que nunca tocan llamadas ni streaming. Mal para cualquier cosa que sí — algunos sitios ya usan la presencia de WebRTC como prueba de que hay alguien vivo.
UDP desactivado
La API existe y responde, pero no sale UDP, así que no se produce candidato srflx. Menos llamativo que quitarlo del todo, y cierra la fuga de verdad. También rompe la funcionalidad real de WebRTC, lo que puede importar o no.
Real
Deja pasar todo sin tocarlo. Esto es correcto en exactamente una situación: cuando tu proxy también maneja UDP. Un proxy SOCKS5 con asociación UDP, o una VPN a nivel de sistema, enruta el paquete STUN por la misma salida que tu tráfico HTTP, y la dirección reflejada es la del proxy. En ese montaje, el WebRTC real es la opción más auténtica disponible. Verifícalo en vez de darlo por supuesto.
Alterado
Sustituye la dirección pública descubierta por la salida del proxy antes de que llegue a JavaScript. WebRTC sigue funcionando, los candidatos están en la cantidad habitual y concuerdan con el camino HTTP. Es la configuración más convincente cuando se hace a nivel de motor: la sustitución tiene que ocurrir donde se generan los candidatos, no en un script de contenido, o los dos se contradicen y vuelves al punto de partida.
Probarlo como es debido
Casi todos los «test de fuga de WebRTC» solo dicen si apareció una dirección pública. Esa no es la pregunta. La pregunta es si coincide con tu proxy.
El procedimiento fiable lleva dos minutos:
- Anota la dirección de salida que se supone que te da el proxy.
- Carga
browserleaks.com/webrtcen el perfil y lee la fila de la IP pública. - Compara. Igual, bien. Distinta es una fuga, aunque la dirección distinta no sea la de tu casa: una dirección de centro de datos apareciendo junto a un camino HTTP residencial ya es una contradicción por sí misma.
- Repite con el proxy del perfil apagado. Si el valor no cambia, WebRTC no está pasando por el proxy en absoluto y la coincidencia anterior fue suerte.
Ese cuarto paso es el que la gente se salta, y es el que pilla una mala configuración.
Dónde encaja entre todo lo demás
WebRTC tiene merecida su fama, pero conviene mantenerlo en proporción. Es una señal, y de las más fáciles de cerrar para siempre: la configuras una vez por perfil, la verificas una vez y queda resuelta.
Lo que no es, es un sustituto del resto. Un perfil con un manejo perfecto de WebRTC y un fingerprint incoherente caerá por la incoherencia. Un perfil detrás de un proxy de centro de datos caerá por el ASN, filtre WebRTC o no.
El motivo para arreglarlo primero no es que sea la señal más importante. Es que es la única que falla en silencio, y los fallos silenciosos son los que descubres por un correo de suspensión.