Fingerprinting Navigator : fuites du navigateur
Comment des valeurs navigator comme platform, hardwareConcurrency, deviceMemory, languages et userAgentData forment un signal d’empreinte, et comment vérifier leur cohérence.
BotBrowser Team
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.
Une page peut lire navigator.platform, navigator.hardwareConcurrency, navigator.deviceMemory, navigator.languages et navigator.userAgentData avant même de demander une seule autorisation, et un script qui note toutes ces valeurs obtient une description compacte de la machine derrière la requête. BotBrowser charge ces valeurs depuis un profil dans un contexte contrôlé, de sorte que le fil principal, un Web Worker et les en-têtes Sec-CH-UA décrivent le même appareil. La suite explique comment ces valeurs se combinent en un signal d'empreinte, où une valeur modifiée commence à contredire ses voisines, et comment vérifier la cohérence avant qu'un site ne le fasse.
Résumé
- Les valeurs
navigatorse lisent sans aucune demande d'autorisation et se jugent ensemble, si bien qu'une valeur courante dans une compagnie improbable pèse plus qu'une lecture isolée. userAgent,platform,vendor,userAgentDataet l'en-têteSec-CH-UArépondent deux fois aux mêmes questions ; appliquer le changement à un seul laisse un désaccord visible.- Une modification faite dans le script de la page n'atteint ni un Web Worker ni un en-tête de requête, car les deux lisent depuis une autre portée.
- BotBrowser tire les valeurs navigator du profil chargé,
--bot-network-info-overridecouvrenavigator.connection, et changer de profil vaut mieux que corriger un champ isolé.
Sommaire
- Quelles valeurs navigator forment le signal
- Pourquoi une seule valeur modifiée crée une incohérence
- Vérifier la cohérence entre les threads et les en-têtes
- Démarrer avec un profil
- Ce que BotBrowser contrôle et ce qu'il ne contrôle pas
- Questions sur les valeurs navigator
- Conclusion pratique
Quelles valeurs navigator forment le signal
L’objet navigator est l’endroit le plus élémentaire où une page apprend dans quel navigateur elle s’exécute. Il ne demande aucune autorisation, il est disponible dès qu’un script démarre, et une grande part du code web ordinaire le lit pour des raisons légitimes, comme choisir une mise en page, dimensionner un ensemble de workers ou sélectionner une langue d’affichage. Cette même disponibilité en fait une entrée courante pour le fingerprinting. Aucune propriété ne suffit à identifier une personne. Le signal vient de la combinaison : un script lit de nombreuses valeurs, les réunit en un seul enregistrement et compare cet enregistrement à ceux qu’il a déjà vus. BotBrowser peut charger les valeurs navigator d’un profil cohérent dans un contexte contrôlé ; il ne peut pas changer la façon dont un site combine ou évalue ces valeurs.
Le guide du W3C sur l’atténuation du fingerprinting dans les spécifications web décrit directement ce schéma. Chaque capacité du navigateur ajoute un peu de variation qu’un script peut lire, et de nombreuses petites différences réunies peuvent suffire à distinguer des navigateurs même si aucune valeur isolée ne paraît inhabituelle. C’est pourquoi les sections suivantes ne citent aucun chiffre fixe d’unicité pour les valeurs navigator. Le caractère identifiant d’une combinaison dépend de la population de navigateurs que voit réellement un site, et un chiffre mesuré sur une audience ne se transpose pas à une autre.
Le schéma montre les deux moitiés du sujet. Lorsqu’une même description d’appareil alimente tous les endroits qui répondent à une question sur navigator, les réponses concordent. Lorsqu’une seule valeur est modifiée, les valeurs liées continuent de décrire l’appareil d’origine, et le désaccord devient un signal à part entière.
Valeurs d’identité : userAgent, platform et vendor
navigator.userAgent est la valeur la plus ancienne et la plus souvent lue. Elle contient le nom du navigateur, une version et un jeton du système d’exploitation. Les navigateurs basés sur Chromium réduisent désormais le détail de cette chaîne : la version du système d’exploitation et la version mineure du navigateur n’y figurent plus, et les détails les plus fins ont migré vers les User-Agent Client Hints. navigator.platform est une chaîne courte comme "Win32", "MacIntel" ou "Linux x86_64". MDN la signale comme obsolète, mais les navigateurs actuels renvoient toujours une valeur et les scripts la lisent toujours. navigator.vendor renvoie une chaîne de fournisseur qui diffère selon les familles de navigateurs.
Ces trois valeurs décrivent les deux mêmes faits, quel navigateur c’est et sur quel système d’exploitation il tourne, de sorte qu’un script peut vérifier qu’elles concordent entre elles. Un navigateur non modifié réussit cette vérification sans effort, car toutes les valeurs proviennent de la même installation. Un navigateur modifié ne la réussit que si toutes les valeurs liées ont été modifiées ensemble.
Valeurs matérielles, de langue et de connexion
navigator.hardwareConcurrency renvoie le nombre de processeurs logiques disponibles pour exécuter des threads. Les navigateurs peuvent indiquer un nombre inférieur ou arrondi par rapport à celui de la machine réelle, il faut donc le traiter comme un indice qui dépend du matériel et du navigateur, et non comme un inventaire précis. navigator.deviceMemory est une approximation de la mémoire vive de l’appareil en gigaoctets. Elle n’existe que dans les navigateurs basés sur Chromium, n’est disponible que dans les contextes sécurisés et la valeur indiquée est plafonnée à 8, si bien qu’une machine dotée de plus de mémoire indique quand même 8. Ces deux valeurs peuvent être lues dans un Web Worker comme sur la page principale, ce qui compte pour les vérifications présentées plus loin dans cet article.
navigator.language renvoie la langue préférée et navigator.languages renvoie la liste ordonnée des langues préférées, par exemple en-US suivi de en. La liste et l’en-tête de requête Accept-Language découlent normalement du même réglage du navigateur, de sorte que la valeur lue par une page et celle reçue par un serveur décrivent les mêmes préférences. Une liste inhabituellement longue, inhabituellement courte ou peu probable pour la région indiquée rend la combinaison plus facile à distinguer.
navigator.connection expose effectiveType, downlink, rtt et saveData dans les navigateurs basés sur Chromium. Ces valeurs décrivent les conditions du réseau et non le matériel, et les en-têtes Client Hints correspondants peuvent transmettre la même information dans les requêtes. La prise en charge diffère selon les navigateurs et les mesures peuvent changer avec le réseau, ce qui les distingue des valeurs matérielles ci-dessus. Elles font tout de même partie du même enregistrement qu’assemble un script.
Client Hints et userAgentData
navigator.userAgentData est la contrepartie structurée de la chaîne User-Agent dans les navigateurs basés sur Chromium. Il expose directement la liste des marques du navigateur, un indicateur mobile et le nom de la plateforme. Sa méthode getHighEntropyValues() renvoie plus de détails à la demande, comme la version de la plateforme, l’architecture, le nombre de bits, le modèle et la liste complète des versions. La même information circule dans les en-têtes de requête Sec-CH-UA. La liste des marques, l’indicateur mobile et la plateforme sont envoyés par défaut, tandis que les valeurs à plus forte entropie ne sont envoyées qu’après que le serveur les a demandées dans un en-tête de réponse Accept-CH.
Trois endroits répondent donc aux questions sur le même navigateur : la chaîne User-Agent, l’objet userAgentData et les en-têtes Client Hints. Un navigateur cohérent donne la même réponse dans les trois, et un script ou un serveur qui les compare n’a besoin que de quelques lignes de code pour le faire.
Les configurations courantes sont partagées par un très grand nombre de navigateurs, et les configurations inhabituelles par très peu. Un nombre de cœurs typique d’un ordinateur portable, une chaîne de plateforme répandue et une liste de langues courante en disent peu à eux seuls. Un nombre de cœurs très éloigné de ce que les appareils grand public indiquent d’ordinaire, un niveau de mémoire rarement vu ou une liste de langues inhabituelle réduisent le groupe de navigateurs qui auraient pu produire cet enregistrement. L’effet exact dépend de l’audience du site qui le collecte, ce qui explique qu’aucun chiffre unique ne soit donné ici.
Pourquoi une seule valeur modifiée crée une incohérence
La leçon pratique est que les valeurs navigator ne sont pas indépendantes. Elles décrivent une seule machine, et un site peut vérifier qu’elles décrivent bien la même. Lorsqu’une seule valeur change, les autres continuent de décrire la machine d’origine, et l’écart entre elles est un signal à part entière.
Une chaîne User-Agent modifiée
Remplacer la chaîne User-Agent est l’approche la plus ancienne. Supposons qu’une extension remplace navigator.userAgent par une chaîne macOS alors que navigator.platform renvoie toujours "Win32". Les deux valeurs désignent désormais des systèmes d’exploitation différents. Le même problème apparaît lorsque navigator.userAgentData indique toujours la plateforme d’origine, ou lorsque les en-têtes Client Hints sont générés à partir de réglages différents de ceux des valeurs JavaScript.
Un site n’a pas besoin de savoir laquelle des valeurs est vraie. Il lui suffit de constater qu’elles se contredisent, et une contradiction est plus distinctive que chaque valeur prise isolément.
Valeurs aléatoires
La randomisation a une faiblesse comparable. Choisir au hasard un nombre de cœurs et une valeur de mémoire pour chaque session produit des combinaisons que peu d’appareils réels possèdent, par exemple une chaîne de plateforme mobile à côté d’un nombre de cœurs propre à un poste de bureau, ou une valeur de mémoire qui ne cadre pas avec le reste du matériel indiqué.
Une valeur qui change à chaque visite échoue aussi au test de stabilité le plus simple, car un navigateur réel indique les mêmes chiffres matériels la fois suivante. Les valeurs à la fois inhabituelles et instables sont plus distinctives que les valeurs réelles qu’elles remplacent.
Modifications faites au mauvais endroit
L’endroit où l’on modifie compte autant que ce que l’on modifie. Un script injecté dans la page ne peut agir que sur ce que lit le fil principal. Un Web Worker a sa propre portée globale et son propre navigator, de sorte qu’une modification au niveau de la page qui n’atteint pas les workers laisse les valeurs d’origine visibles à cet endroit. Les en-têtes de requête sont produits par le code réseau du navigateur et non par le script de la page, si bien qu’une modification au niveau de la page ne les change jamais. Le résultat : trois réponses là où il devrait y en avoir une.
Les autres mesures courantes ne traitent pas non plus ce signal. Un VPN change l’adresse réseau et laisse les valeurs navigator telles quelles. La navigation privée conserve les mêmes valeurs de matériel et de langue. Effacer les cookies supprime l’état stocké, mais ne modifie pas ce que le navigateur indique de lui-même.
Un court ensemble de règles décrit ce que signifie la cohérence en pratique :
- Le système d’exploitation de la chaîne User-Agent correspond à
navigator.platformet à la plateforme denavigator.userAgentData. - La marque et la version majeure du navigateur concordent entre la chaîne User-Agent, la liste des marques de
userAgentDataet l’en-têteSec-CH-UA. - Le nombre de cœurs et le niveau de mémoire sont plausibles pour la classe d’appareil qu’implique la plateforme.
navigator.languagesest plausible pour la région indiquée et concorde avec l’en-têteAccept-Language.- Chacune de ces valeurs est identique dans le fil principal, dans les workers et d’une session répétée à l’autre.
Vérifier la cohérence entre les threads et les en-têtes
L’objectif de la vérification n’est pas de trouver un nombre correct. Il s’agit de confirmer que chaque endroit qui répond à une question sur navigator donne la même réponse. Les vérifications ci-dessous ne demandent qu’un navigateur et une page de test que vous contrôlez, et n’exigent de visiter aucun site tiers.
Fil principal et Web Worker
Ouvrez une page que vous contrôlez et lisez les valeurs dans le fil principal : la chaîne User-Agent, la plateforme, le fournisseur, le nombre de processeurs logiques, la mémoire de l’appareil, la liste des langues, ainsi que la liste des marques et la plateforme de navigator.userAgentData. Notez-les. Démarrez ensuite un Web Worker dédié depuis la même page, faites-lui lire les mêmes propriétés depuis son propre navigator et renvoyer le résultat à la page.
Comparez les deux enregistrements champ par champ. Ils doivent être identiques. Une différence signifie en général qu’une valeur a été définie par le script de la page, ou que le worker lit à une source différente de celle de la page. Un worker dédié est le plus simple à tester, et les workers partagés et les service workers peuvent être ajoutés à la même comparaison.
En-têtes Client Hints
Comparez ensuite le résultat de getHighEntropyValues() avec ce que reçoit un serveur. La méthode renvoie une promesse pour les valeurs que vous listez, par exemple la version de la plateforme, l’architecture, le nombre de bits et la liste complète des versions. Côté serveur, les en-têtes à plus forte entropie n’arrivent qu’après qu’une réponse précédente a inclus un en-tête Accept-CH qui les demande. La page de test a donc besoin d’un serveur que vous contrôlez, qui envoie Accept-CH et enregistre les en-têtes de requête qu’il reçoit.
Comparez la liste des marques et la plateforme de Sec-CH-UA et Sec-CH-UA-Platform avec l’objet userAgentData, puis comparez les en-têtes de version de plateforme et d’architecture avec le résultat à forte entropie. Tous doivent décrire le même navigateur et la même plateforme que la chaîne User-Agent.
Sessions répétées
Fermez le navigateur, démarrez une nouvelle session avec le même profil et la même configuration, puis relancez les mêmes vérifications. Les valeurs qui décrivent la plateforme et le matériel doivent être les mêmes à chaque session. Si vous voulez confirmer que les valeurs changent ensemble, lancez une session de plus avec un profil différent et vérifiez que toutes les vues passent en même temps à la nouvelle description de l’appareil.
Gardez fixes la version du navigateur et celle du profil pendant une comparaison. Un changement de version modifie légitimement les valeurs de marque et de version, et mêler ce changement à la comparaison masque le résultat que vous cherchez.
La liste de vérification complète, dans l’ordre :
- Notez les valeurs navigator dans le fil principal.
- Notez les mêmes valeurs dans un Web Worker et comparez-les champ par champ.
- Demandez les valeurs à forte entropie et comparez-les avec la liste des marques et la plateforme de
userAgentData. - Capturez les en-têtes Client Hints sur un serveur que vous contrôlez et comparez-les avec les valeurs JavaScript.
- Répétez le tout dans une nouvelle session avec le même profil et comparez les enregistrements.
- Changez un seul réglage à la fois et répétez la comparaison après chaque changement.
Considérez le premier désaccord comme le résultat. Notez quelles deux vues divergent et revenez à la configuration au lieu d’ajouter une autre modification par-dessus, car chaque modification supplémentaire ajoute un endroit de plus où des écarts peuvent apparaître.
Démarrer avec un profil
Avec BotBrowser, les valeurs navigator proviennent du profil chargé, et le démarrage le plus simple est donc un profil et un répertoire de données utilisateur temporaire :
chrome --bot-profile="path/to/profile.enc" \
--user-data-dir="$(mktemp -d)"
La documentation de BotBrowser décrit le profil comme la source des valeurs d’identité, de matériel, de paramètres régionaux, de réseau et de périphériques multimédias, et indique que les valeurs JavaScript, les en-têtes HTTP et les contextes Worker renvoient à partir de lui des valeurs cohérentes. Commencez par cette base et exécutez les vérifications ci-dessus avant d’ajouter tout autre paramètre. Sans profil, les valeurs navigator reflètent la machine sur laquelle vous travaillez réellement.
La langue et les paramètres régionaux peuvent être définis explicitement avec --bot-languages et --bot-locale. Pour les informations réseau, --bot-network-info-override contrôle les valeurs de navigator.connection et les en-têtes Client Hints correspondants, et la documentation limite la politique obtenue au BrowserContext. Définissez-le avant de créer la première page de ce contexte, afin que toutes les pages et tous les workers du contexte voient les mêmes valeurs.
chrome --bot-profile="path/to/profile.enc" \
--bot-languages="en-US,en" \
--bot-locale="en-US" \
--bot-network-info-override \
--user-data-dir="$(mktemp -d)"
Il vaut mieux choisir un autre profil que de remplacer des valeurs isolées par-dessus un profil existant. Un profil est construit pour que les valeurs liées concordent, et modifier l’une d’elles, le nombre de cœurs par exemple, laisse inchangées les valeurs qui en dépendent. Le contrôle personnalisé du User-Agent, les paramètres de langue et de paramètres régionaux et certains paramètres d’identité, comme la marque et la version du navigateur, sont limités par niveau de licence dans la documentation ; vérifiez donc ce que comprend votre licence avant de vous appuyer dessus.
Ce que BotBrowser contrôle et ce qu’il ne contrôle pas
BotBrowser dérive les valeurs navigator (userAgent, platform, hardwareConcurrency, deviceMemory, languages et userAgentData) du profil chargé, de sorte que le fil principal, les workers et les en-têtes Client Hints renvoient un seul ensemble cohérent, et le paramètre --bot-network-info-override contrôle les valeurs de navigator.connection et les Client Hints correspondants, ce qui vous offre une configuration reproductible pour exécuter les vérifications de cohérence ci-dessus. BotBrowser ne peut pas empêcher les sites de collecter les valeurs navigator ni de les corréler avec d’autres signaux, ne peut pas garantir qu’un profil corresponde au matériel réel ou aux attentes d’un site, et ne remplace pas la cohérence du réseau, du compte ou du comportement ; le contrôle personnalisé du User-Agent dépend du niveau de licence.
Il faut détailler ces limites, car un ensemble cohérent de valeurs navigator ne répond qu’à l’une des questions qu’un site peut poser.
- Un site peut toujours lire les valeurs navigator et les combiner avec des signaux de canvas, de WebGL, de polices et d’écran. Chacune de ces surfaces demande son propre examen.
- Un profil décrit un appareil, il n’est pas cet appareil. Un site peut avoir des attentes sur le matériel ou le logiciel qu’aucun profil ne peut connaître à l’avance.
- La localisation réseau, l’historique du compte, la réputation et le comportement sont des entrées distinctes. Des valeurs navigator cohérentes ne modifient aucune d’entre elles.
- Le comportement documenté s’applique à un profil valide chargé dans une configuration prise en charge ; vérifiez-le donc dans votre propre configuration avec la liste de vérification ci-dessus.
Considérez la cohérence de navigator comme une partie d’une configuration consistante. La liste de vérification vous dit si cette partie tient, et elle ne dit rien de la façon dont un site donné traitera une session.
Questions sur les valeurs navigator
Q : hardwareConcurrency suffit-il à identifier quelqu’un ? R : Non. C’est une entrée parmi beaucoup d’autres. Les valeurs courantes sont partagées par de nombreux navigateurs et les valeurs rares réduisent davantage le groupe, mais le signal utile vient de la combinaison avec la plateforme, la mémoire, la langue et les autres surfaces.
Q : Pourquoi deviceMemory s’arrête-t-il à 8 ? R : La valeur est une approximation, et les navigateurs basés sur Chromium la plafonnent pour limiter la précision avec laquelle elle décrit la machine. Les autres familles de navigateurs n’exposent pas du tout la propriété, son absence y est donc normale.
Q : Modifier seulement la chaîne User-Agent est-il utile ?
R : Non, tant que navigator.platform, navigator.userAgentData ou les en-têtes Client Hints décrivent encore le navigateur d’origine. Les valeurs liées doivent changer ensemble.
Q : Un VPN ou la navigation privée changent-ils les valeurs navigator ? R : Non. Les valeurs proviennent du navigateur et du système d’exploitation, pas de la route réseau ni du mode de navigation.
Q : Pourquoi comparer un Web Worker avec le fil principal ?
R : Un worker a son propre navigator. Une valeur modifiée uniquement dans le script de la page y reste inchangée, le worker est donc l’endroit le plus rapide pour repérer une lacune.
Q : BotBrowser rend-il un profil égal au matériel réel ? R : Non. Le profil définit les valeurs que le navigateur indique et les maintient cohérentes d’un contexte à l’autre. Il ne transforme pas la machine en l’appareil que décrit le profil.
Pour des sujets connexes, consultez Client Hints, le nombre de cœurs du processeur, fuseau horaire, paramètres régionaux et langue et informations réseau. L’ensemble des contrôles se trouve sur la page des fonctionnalités, et vous pouvez vérifier vous-même la cohérence de navigator dans le Centre de preuves.
Conclusion pratique
Partez d'un profil plutôt que d'une liste de substitutions. Chargez un profil, lisez les sept valeurs qui portent l'essentiel du signal (navigator.userAgent, navigator.platform, navigator.vendor, navigator.hardwareConcurrency, navigator.deviceMemory, navigator.languages, navigator.userAgentData) et notez ce que chacune renvoie.
- Comparez cet enregistrement avec la même lecture dans
new Worker('worker.js'); un écart indique une valeur posée par le script de la page. - Comparez
userAgentData.brandset la plateforme avec les en-têtesSec-CH-UAetSec-CH-UA-Platformque votre serveur reçoit après avoir envoyéAccept-CH. - Répétez la lecture dans une session neuve avec le même profil ; les valeurs de plateforme et de matériel ne doivent pas bouger d'une session à l'autre.
- Si deux vues divergent, remplacez le profil plutôt que la valeur, car une seconde substitution ajoute un second endroit où l'écart peut apparaître.
Un ensemble qui passe ces quatre étapes est cohérent, et la cohérence est tout ce que cette surface affirme : le navigateur répond partout de la même façon à une même question, ce qui ne dit encore rien de la façon dont un site traitera la session.
Sources
Références publiques utilisées pour les affirmations sur navigator, Client Hints et BotBrowser dans cet article :
Cet article fait partie du guide : Qu'est-ce qu'une empreinte de navigateur ?
Articles Connexes
Client Hints Fingerprinting : en-têtes HTTP et identité
EmpreinteComment hardwareConcurrency révèle les cœurs réels de votre CPU
IdentitéUser-Agent et Client Hints : garder une identité cohérente
EmpreinteFingerprinting de la Network Information API : revue de politique
EmpreinteDevice Memory API et performances web : indication mémoire
EmpreinteVie privée du navigateur entre surfaces : garder un contexte cohérent
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.