Retour au Centre de connaissances
Réseau

Qu'est-ce qu'une fuite d'IP WebRTC ? Prévention et vie privée

Qu'est-ce qu'une fuite d'IP WebRTC ? Découvrez comment les candidats ICE exposent l'identité réseau et comment vérifier la cohérence du proxy.

BotBrowser Team

Documentation

Vous préférez la doc produit maintenue ?

Cet article a une page équivalente dans le centre de documentation. Utilisez les docs pour le flux canonique, les flags à jour et la référence durable.

WebRTC offre à la page une seconde vue du réseau. Avant qu'un appel ne s'établisse, le navigateur peut indiquer quelles interfaces locales existent, quelle adresse publique un serveur STUN a observée et quel relais a répondu. BotBrowser configure la liste de serveurs ICE et les candidats exposés, et aligne ces observations sur un profil et une route approuvée pour les chemins que le navigateur envoie par cette route, mais ne peut pas garantir qu'un relais, un pair ou le réseau d'origine ne révèle pas une adresse par un autre chemin.

TL;DR

  • Le proxy réécrit les requêtes HTTP et la collecte peut suivre un autre chemin, donc une page chargée correctement ne dit rien de WebRTC.
  • Chaque type déclare un fait distinct : host une interface locale, srflx l'adresse vue par un serveur STUN, relay un point TURN et prflx une correspondance découverte par le pair.
  • BotBrowser choisit la liste de serveurs ICE et les informations exposées avec --bot-webrtc-ice, tandis que --bot-webrtc=profile et --bot-webrtc=disabled décident si WebRTC suit le profil ou disparaît.
  • La preuve de version, c'est iceGatheringState à complete, une grille dans chrome://webrtc-internals conforme à la route approuvée et getStats() qui signale le même candidat local.

Sommaire

Voir la vidéo

Cette vidéo en anglais montre ce qu'une page apprend de la collecte RTCPeerConnection avant le début d'un appel. Une page de laboratoire locale déclare trois jeux de candidats et un script lit chacun avec le rappel habituel, puis compare chaque adresse server-reflexive déclarée avec l'adresse déclarée visible par HTTP. Le même appel a ensuite été exécuté dans Google Chrome officiel avec une liste de serveurs ICE vide : deux lignes de candidat host sur une machine Windows et une sur une machine Ubuntu, chacune portant un nom mDNS. La vidéo montre ce que ces deux machines ont renvoyé, et une liste identique signifie une cohérence, pas un anonymat. Aucun profil BotBrowser n'intervient. L'audio est en anglais.

Ce qu'expose un candidat collecté

Un candidat est un chemin possible pour les médias, et son champ type indique comment le navigateur a connu ce chemin : host, srflx, prflx ou relay. Chrome produit normalement les quatre pendant la préparation d'un appel, et chacun répond à une question différente sur le réseau derrière la session. La question utile n'est pas de savoir si un candidat existe, mais ce que ce candidat permet de conclure sur la machine, la route et le relais qui a répondu.

TypeCe que la page apprendChamp dans chrome://webrtc-internalsAttendu dans un contexte contrôlé
hostUne valeur d'interface locale, ou un nom mDNS qui la masqueLigne candidate de la description localeUn nom mDNS, ou une valeur définie par le profil
srflxL'adresse publique vue par un serveur STUNLigne candidate avec relatedAddressLa sortie approuvée, pas le lien montant de l'hôte
relayLe point TURN qui portera les médiasLigne candidate avec typ relayPrésent quand TURN est configuré et joignable
prflxUne correspondance découverte par le pair pendant les vérificationsLigne candidate-pair de la vue statistiqueAbsent, ou conforme à la route approuvée

Ce tableau compte parce qu'un déploiement peut réussir une ligne et échouer sur une autre. Un profil qui masque les valeurs des interfaces privées laisse encore des lignes srflx qui décrivent la sortie réelle de la requête STUN, et un relais TURN ajoute une seconde valeur publique que le pair verra pendant les médias. Examiner les quatre types séparément rend aussi un rapport d'échec précis : une ligne relay manquante désigne l'entrée TURN ou le chemin UDP, alors qu'une ligne prflx inattendue désigne le côté pair de la connexion.

Candidats host et nom mDNS

Les candidats host décrivent une interface réseau de la machine qui exécute le navigateur. Chrome moderne masque les valeurs IPv4 et IPv6 privées derrière un nom mDNS comme 4f2a9c1e-7b3d-4a52-9e88-1c6d0b8f2e11.local, donc la page sait qu'une interface existe sans connaître la valeur derrière. C'est une limite réelle, et elle est aussi incomplète : le nom mDNS reste stable pendant la vie du profil, il apparaît dans la description locale et il réapparaît dans la vue statistique sous local-candidate. Une page peut comparer deux visites et savoir si les deux ont utilisé la même interface, ce qui explique que Candidats mDNS WebRTC et confidentialité du réseau local traite le nom comme un point à vérifier et non comme un cas réglé.

La collecte host a toujours lieu quand la machine est derrière un proxy. Le proxy change la sortie des requêtes de page ; il ne supprime pas les interfaces locales, donc le navigateur continue de les énumérer sauf si la politique du profil en décide autrement. Un contexte contrôlé doit donc afficher un nom mDNS ou une valeur définie par le profil, et le registre de déploiement doit préciser lequel des deux le profil produit.

Candidats server-reflexive et valeur observée

Les candidats srflx existent parce que le navigateur a envoyé une requête de liaison STUN à un serveur et que la réponse a nommé la source vue par ce serveur. Le chemin courant utilise stun:stun.l.google.com:19302 sur udp:3478. La réponse porte la valeur publique attribuée et le champ relatedAddress conserve la valeur locale qui l'a produite, donc une ligne peut contenir les deux côtés de la même correspondance.

La ligne srflx est celle que citent le plus souvent les rapports de fuite, parce qu'elle décrit quelque chose que l'hôte n'a pas choisi. Quand la requête passe par une route approuvée, cette valeur est la sortie de la route. Quand elle part directement, la valeur est le lien montant de l'hôte. Les deux résultats se ressemblent dans la liste, et c'est pourquoi l'examen doit consigner la route et pas seulement la valeur, et que Cohérence du proxy entre DNS et WebRTC compare la sortie HTTP, la réponse du résolveur et la valeur du candidat en une seule passe.

Candidats relay et peer-reflexive

Les candidats relay apparaissent quand un serveur TURN est configuré et joignable. Le navigateur attribue une valeur sur le serveur, puis les médias passent par turn:relay.example.com:3478?transport=udp. La ligne nomme le point TURN plutôt que l'hôte, c'est donc la ligne qui montre qu'un déploiement dispose d'un chemin média indépendant du lien local.

Les candidats prflx apparaissent quand une vérification du pair atteint le navigateur depuis une valeur que celui-ci n'avait pas prévue. La ligne est créée à partir de cette vérification et non de l'énumération locale, elle enregistre donc ce qu'une autre partie a vu. Un contexte contrôlé qui affiche une ligne prflx possède la preuve qu'un chemin a évité la correspondance prévue, et l'examen doit le traiter comme une question sur le pair et le chemin, non sur le profil.

Quatre lignes comparent les candidats host, srflx, relay et prflx avec les champs à lire dans chrome://webrtc-internals et la valeur attendue dans un contexte contrôlé

Où s'arrête le contrôle du navigateur

Les limites se décrivent mieux une fois les quatre types connus. Chaque approche ci-dessous change ce que la page ou l'interface du navigateur signale, et aucune ne change ce qu'un pair ou un serveur TURN observe quand les médias circulent.

Réglages et modules d'extension

Désactiver WebRTC dans les réglages du navigateur, par exemple avec media.peerconnection.enabled dans Firefox, supprime toute la collecte. L'absence est observable : une page peut tester si RTCPeerConnection existe et si createOffer() aboutit, et un navigateur sans cette interface se distingue dans la population que la page attend.

Les modules peuvent intercepter onicecandidate, réécrire les listes RTCIceServer ou remplacer le constructeur. Ils s'exécutent après que le code natif de collecte a produit ses valeurs, donc une valeur obtenue par la voie du prototype peut encore différer de celle utilisée par la couche réseau. La modification laisse aussi des traces dans la forme de l'objet : autre chaîne de prototypes, accesseur qui renvoie une valeur changée, ou rappel déclenché plus tard que la page ne l'attend.

Limites du VPN et du relais

Un VPN place toutes les connexions du système dans un tunnel, ce qui change ce que voit le serveur STUN mais pas ce que la machine énumère. Les lignes host décrivent toujours les interfaces locales et les médias négocient toujours avec le pair sauf si un relais TURN est exigé. Le tunnel ajoute en plus une seconde sortie que le déploiement n'a peut-être pas approuvée, et un examen qui ne regarde que le proxy la manquera.

Les services de relais ont leurs propres limites. Un point TURN répond avec une valeur de son propre groupe, généralement dans une région choisie à la souscription, et cette valeur différera de la sortie du proxy. L'écart est attendu et doit être consigné, car un examen qui traite chaque nouvelle valeur comme une fuite reposera sans fin la même question.

Comment BotBrowser gère les serveurs ICE et les candidats

BotBrowser modifie la liste de serveurs ICE et les informations de candidats exposées par le navigateur, à partir du profil chargé et des options de lancement. Les contrôles se situent sous la couche JavaScript, donc une page qui lit pc.localDescription ou pc.getStats() reçoit les valeurs produites par le profil et les options.

Trois options pour la configuration ICE

OptionCe qu'elle sélectionneCe qui reste hors de sa portée
--bot-webrtc-ice="google"Liste de serveurs stun:stun.l.google.com:19302Si udp:3478 atteint ce serveur
--bot-webrtc-ice="custom:..."Une liste STUN ou TURN nomméeLes identifiants de ce relais
--bot-webrtc=profileLes réglages WebRTC enregistrés dans le profilLa route du proxy
--bot-webrtc=disabledLe retrait de la capacité WebRTCRien : l'absence est visible pour la page

La distinction entre les deux familles mérite d'être conservée. --bot-webrtc-ice choisit les serveurs et --bot-webrtc choisit la posture. Un lancement qui ne fixe que la posture garde la liste du profil, et un lancement qui ne fixe que la liste garde la posture déjà enregistrée. Lire l'une des deux et supposer l'autre, c'est ainsi qu'un déploiement finit avec un profil qui semble correct et une session qui collecte par une autre route.

Options et chemins proxy

Un lancement courant associe le préréglage à un proxy et à une politique DNS locale :

chrome --bot-profile="path/to/profile.enc" \
       --proxy-server="socks5://user:[email protected]:1080" \
       --bot-webrtc-ice="google" \
       --bot-local-dns \
       --bot-timezone="America/New_York" \
       --bot-locale="en-US"

Une liste propre nomme directement les serveurs STUN et TURN :

chrome --bot-profile="path/to/profile.enc" \
       --proxy-server="socks5://user:[email protected]:1080" \
       --bot-webrtc-ice="custom:stun:stun.example.com:3478,turn:turn.example.com:3478?transport=udp"

L'automatisation transmet les mêmes valeurs par les arguments de lancement :

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: 'path/to/botbrowser/chrome',
    args: [
      '--bot-profile=path/to/profile.enc',
      '--proxy-server=socks5://user:[email protected]:1080',
      '--bot-webrtc-ice=google',
      '--bot-local-dns',
    ],
    headless: true,
  });

  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

Chemins à travers un relais

Un chemin média approuvé doit atteindre le point TURN depuis le navigateur, et le transport décide s'il le peut. Quand le service proxy transporte UDP, socks5://user:[email protected]:1080 transporte aussi le trafic STUN et TURN, donc les requêtes de page et les médias partagent une route. Quand il ne transporte que TCP, turn:turn.example.com:3478?transport=udp ne répondra pas à travers lui et un relais ?transport=tcp doit être approuvé comme chemin distinct. UDP sur SOCKS5 : routage privé de QUIC et WebRTC détaille les décisions de transport par contexte et les vérifications associées.

Vérifier le jeu de candidats avant diffusion

Une vérification comporte trois parties : l'état de collecte, la grille qui énumère chaque candidat et l'enregistrement statistique de la paire qui a porté les médias. Les trois ensemble prennent quelques minutes et laissent des preuves qu'un examen ultérieur peut comparer au registre de déploiement.

Lire l'état de collecte dans chrome://webrtc-internals

Ouvrez chrome://webrtc-internals, lancez la page de test et observez iceGatheringState. Il passe de new à gathering et se termine à complete. La page affiche une grille avec une ligne par candidat, la colonne type, l'address, le port, le protocol et la valeur relatedAddress. Une grille qui n'atteint jamais complete signifie que la collecte continue ou qu'elle est bloquée. Une grille qui atteint complete avec seulement des lignes host signifie qu'aucune réponse STUN n'est arrivée.

Comparer la grille avec pc.getStats()

pc.getStats() renvoie des enregistrements local-candidate avec candidateType, address, port, protocol et relatedAddress, ainsi que des enregistrements candidate-pair avec state, nominated, localCandidateId et remoteCandidateId. La paire nommée avec state: succeeded est le chemin qui a porté les médias. Recherchez son localCandidateId, puis confirmez que la ligne local-candidate correspondante signale le type et la valeur montrés dans la grille. Deux vues qui divergent, par exemple une ligne de grille avec un nom mDNS et une ligne statistique avec une valeur IPv4 privée, signifient que la page et les médias ont utilisé des interfaces différentes.

Quand des candidats relay manquent

Un état complete sans ligne relay est l'échec le plus courant, et cet ordre le résout le plus vite :

  1. La liste de serveurs ne contient aucune entrée TURN. La grille n'affiche alors que des lignes host et srflx, ce que produit par conception un lancement avec --bot-webrtc-ice="google".
  2. L'URL TURN n'inclut pas ?transport=udp. Une URL de relais sans paramètre de transport revient à TCP et reste silencieuse sur un chemin qui ne transporte que UDP.
  3. udp:3478 est filtré sur la sortie. L'attribution TURN n'aboutit jamais, aucune ligne relay n'apparaît et chrome://webrtc-internals montre la tentative se terminer sans candidat.
  4. La valeur de --bot-webrtc-ice ne correspond pas au profil. Une liste propre qui nomme un hôte non autorisé par le profil, ou un préréglage sans licence dans le déploiement, laisse le lancement avec une liste que personne n'a choisie, et la grille affiche exactement cette liste.

Chaque étape est une vérification unique, et la grille y répond en général sans lire de journaux : la ligne du point TURN existe ou elle n'existe pas.

Guide de décision pratique

Décidez la posture et la liste de serveurs ensemble, puis vérifiez le résultat par rapport à la route approuvée par le déploiement.

  1. Associez --bot-webrtc-ice à --proxy-server. Sans proxy, la sortie est déjà le lien montant de l'hôte et l'option change seulement le serveur qui la signale.
  2. Utilisez le préréglage google sauf si le déploiement nomme sa propre infrastructure. stun:stun.l.google.com:19302 est la configuration de la majorité du trafic, donc une session qui l'omet paraît inhabituelle pour une autre raison.
  3. Ajoutez --bot-local-dns. La résolution de noms et les médias sont les deux chemins qui laissent le plus souvent le proxy de côté, et traiter les deux raccourcit l'examen.
  4. Recourez à --bot-webrtc=disabled seulement là où l'application n'a réellement aucune fonction média. L'interface absente est visible et une page peut enregistrer cet écart.
  5. Refaites la vérification en trois parties après chaque changement de point proxy, de fournisseur TURN ou de profil. La liste de candidats résulte de ces trois entrées.

BotBrowser casse-t-il les appels ? Non, RTCPeerConnection reste disponible et les médias circulent. Les options changent quels serveurs collectent et quelles valeurs la page reçoit.

Quelle est la différence entre les deux options ? --bot-webrtc-ice choisit les serveurs et --bot-webrtc choisit si WebRTC suit le profil ou est retiré.

Un VPN suffit-il ? Un VPN change la sortie de toutes les connexions mais laisse les lignes host en place et ajoute une sortie que le déploiement n'a peut-être pas approuvée.

Et IPv6 ? Les mêmes quatre types s'appliquent, et une valeur de profil qui couvre IPv4 sans couvrir IPv6 laisse un écart visible entre les deux familles.

Conclusion pratique

Un examen des fuites qui ne lit que le trafic de page manque le chemin pris par les médias. Consignez la posture, la liste de serveurs et la route approuvée ; collectez jusqu'à ce que iceGatheringState indique complete ; comparez la grille avec getStats() ; et gardez le résultat à côté du registre de déploiement. Quand une session ultérieure présente une autre ligne, la comparaison nomme le changement au lieu de laisser l'examinateur le deviner.

Pour les contrôles réseau qui entourent le sujet, voir Configuration du proxy, Prévention des fuites DNS et Isolation de navigateur multicompte. La page des fonctionnalités liste les capacités associées et l'article sur les candidats mDNS WebRTC précise ce que le nom mDNS ajoute à une ligne host.

Sources publiques

#WebRTC#Ip-Leak#proxy#confidentialité#réseau

Faites passer BotBrowser de la recherche à la production

Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.