Retour au Centre de connaissances
Empreinte

Mode déterministe : empreintes reproductibles

Comment une graine de bruit fixe rend reproductibles Canvas, WebGL et Audio d'une session à l'autre, et comment vérifier qu'elle se répète et qu'une autre graine change la sortie.

BotBrowser Team

Documentation

Vous voulez la documentation structurée pour Empreinte ?

Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.

BotBrowser peut répéter le bruit visible du navigateur avec une graine dans un contexte contrôlé, mais ne rend pas identiques les builds, profils, machines ou décisions des sites ; cet article précise cette limite.

TL;DR

Utilisez une --bot-noise-seed positive avec le même profil et le même build lorsqu’un parcours contrôlé doit répéter Canvas, WebGL, Audio et les métriques de texte ; un changement de graine doit être volontaire.

Contents

Sommaire

Pourquoi un bruit reproductible compte

Le bruit d'empreinte remplit deux fonctions qui tirent dans des sens opposés. De petites variations dans Canvas, WebGL, Audio et les mesures de texte empêchent un navigateur de présenter la sortie brute d'une seule machine. Un test ou un flux de travail de longue durée a besoin du contraire : la même sortie quand vous le relancez demain. Si chaque lancement tire un nouveau bruit, vous ne pouvez pas savoir si un résultat différent vient de votre configuration, de la page testée ou du bruit lui-même. BotBrowser peut rejouer la même configuration à graine dans un contexte contrôlé afin que les exécutions restent comparables ; il ne rend pas les résultats identiques d’un build, d’une plateforme ou d’un matériel à l’autre.

Une graine de bruit règle ce conflit. C'est un simple entier qui initialise un générateur de nombres pseudo-aléatoires, de sorte que la suite de valeurs de bruit est fixée par la graine. Deux lancements qui utilisent la même graine appliquent la même variation au même dessin ou à la même mesure, et une autre graine applique une autre variation. Vous décidez quand la sortie doit se répéter et quand elle doit changer.

Les ingénieurs en protection de la vie privée et les testeurs recourent en général à une graine fixe dans quatre situations :

  • Continuité de session. Revenir sur un service au fil de plusieurs lancements en présentant à chaque fois la même sortie de Canvas, WebGL, Audio et des métriques de texte.
  • Identités stables et distinctes. Donner à des comptes ou à des utilisateurs de test séparés leur propre motif de bruit, qui ne change pas d'un lancement à l'autre.
  • Contrôles de configuration. Confirmer qu'un profil et un ensemble d'options produisent la sortie attendue, et que changer la graine produit autre chose.
  • Expériences reproductibles. Retirer le bruit d'empreinte des variables quand vous comparez deux builds, deux pages ou deux profils.

Une graine de bruit alimente un générateur pseudo-aléatoire qui pilote le bruit du Canvas 2D, de WebGL, de l'Audio et des métriques de texte, si bien que le même build, le même profil et la même graine répètent la même sortie

Les sections suivantes suivent la graine depuis les surfaces qu'elle touche, en passant par le choix des valeurs et les arguments de lancement, jusqu'à une routine de vérification et aux limites à prévoir. La référence est la documentation publique sur la reproductibilité de la graine de bruit, et le comportement de Canvas est décrit dans la référence de l'API Canvas de MDN indiquée dans les sources.

Ce que contrôle la graine et ce qu'elle laisse intact

L'option --bot-noise-seed s'applique aux surfaces sur lesquelles BotBrowser ajoute du bruit :

  • Canvas 2D. Formes, texte et lecture des pixels via toDataURL(), toBlob() et getImageData().
  • WebGL et WebGPU. Le rendu qu'une page relit depuis une surface de dessin.
  • Audio. Les valeurs d'échantillons produites par le traitement audio, par exemple un rendu OfflineAudioContext.
  • Métriques de texte. Les mesures renvoyées par measureText(), getBoundingClientRect() et getClientRects().

La graine répète le bruit pour un même contenu. Gardez les observations aléatoires séparées dans Observabilité de l’aléa cryptographique et empreintes du navigateur. Une page qui dessine la même scène avec la graine 42 dans deux sessions relit les mêmes pixels. La même scène avec la graine 43 relit d'autres pixels, tout aussi stables. C'est pourquoi une page de vérification doit dessiner une scène fixe : si le contenu change d'une exécution à l'autre, la sortie change pour des raisons sans rapport avec la graine.

La graine ne touche pas aux valeurs qui proviennent du profil. Les propriétés de navigator, les dimensions d'écran et la chaîne user agent sont lues dans le profil et restent identiques à chaque lancement, quelle que soit la graine. Le stockage, les cookies et l'état de session relèvent aussi d'autre chose. Ils se trouvent dans le répertoire défini par --user-data-dir et dans les valeurs chargées avec --bot-cookies, si bien qu'une graine ne restaure pas une connexion et ne garde pas le souvenir d'une visite précédente.

Chaque canal de bruit dispose en outre de son propre interrupteur dans la référence de la ligne de commande : --bot-noise-canvas, --bot-noise-webgl-image, --bot-noise-audio-context, --bot-noise-client-rects et --bot-noise-text-rects. Ils acceptent true ou false. La graine décide de l'aspect du bruit, et les interrupteurs décident quelles surfaces reçoivent du bruit, de sorte que les deux contrôles répondent à des questions différentes.

La valeur elle-même obéit à deux règles. La plage valide va de 1 à 4294967295, le plus grand entier non signé sur 32 bits. Une valeur de 0 se comporte autrement : elle garde le bruit actif avec les valeurs par défaut du profil mais sans graine déterministe, donc la sortie n'est pas censée se répéter d'une session à l'autre. Si vous avez besoin de répétabilité, choisissez un entier positif et transmettez-le à chaque lancement.

Le temps se contrôle séparément. --bot-time-seed prend un entier de 1 à 4294967295 pour une politique reproductible des durées d'exécution, et 0 la désactive. --bot-time-scale prend un nombre décimal inférieur à 1.0 pour mettre cette politique à l'échelle. --bot-stack-seed accepte profile, real ou un entier positif pour le comportement de la profondeur de pile. Ce sont des contrôles indépendants : une graine de bruit seule ne rend pas les durées répétables, et une graine de temps ne change pas la sortie de Canvas. Quand un test exige que le bruit de rendu et les durées se répètent, définissez les deux valeurs en connaissance de cause et consignez-les toutes les deux. Pour voir comment performance.now, hardwareConcurrency et deviceMemory se combinent en un signal de temps et comment vérifier le temps rapporté, consultez Empreinte du navigateur : signaux de temps, de CPU et de mémoire.

Choisir des graines pour des identités stables

Notez avec chaque attribution le chemin exact de --bot-profile, l'entier --bot-noise-seed, --user-data-dir et le build BotBrowser ; modifier l'une de ces quatre entrées change ce que la comparaison peut établir.

Une façon pratique de voir le couple est la suivante : le profil définit la classe d'appareil et la graine définit le motif de bruit au sein de cette classe. Le profil A avec la graine 100 est une empreinte stable et reproductible. Le profil A avec la graine 200 partage les valeurs du profil mais possède un autre motif de bruit. Le profil B avec la graine 100 a une base différente et donc une sortie différente, même si la valeur de graine est la même. Une graine ne fait jamais produire la même empreinte à deux profils différents, puisque les valeurs de base restent différentes.

Un petit plan pour trois sessions pourrait ressembler à ceci :

  • Session une : profil A avec la graine 100, pour le premier compte ou utilisateur de test.
  • Session deux : profil A avec la graine 200, pour un second compte qui doit garder son propre motif de bruit.
  • Session trois : profil B avec la graine 100, pour une autre classe d'appareil qui réutilise une valeur de graine.

Quelques habitudes gardent ce plan fiable dans la durée. Générez chaque graine une seule fois, puis conservez-la à côté du compte ou du cas de test auquel elle appartient, car la graine ne peut pas être retrouvée plus tard à partir de la sortie. Ne dérivez pas une graine d'une valeur qui change, comme un horodatage ou un compteur qui repart de zéro, car cela ramène discrètement une configuration déterministe à une valeur différente à chaque lancement. Ne réutilisez pas une même graine pour des sessions qui doivent garder des motifs de bruit séparés. Et rangez l'attribution des graines au même endroit que le nom du fichier de profil, afin de pouvoir reconstituer le couple exact plus tard. Pour savoir comment attribuer des graines à des identités sans créer de liens et comment répéter les exécutions en CI, consultez Reproductibilité de la graine de bruit pour des exécutions répétables.

Quand un seul processus du navigateur doit porter plusieurs identités, l'empreinte par contexte (ENT Tier3) permet à chaque BrowserContext d'avoir son propre --bot-noise-seed. La documentation montre les options définies pour un contexte avant la création de sa première page, afin que le moteur de rendu démarre avec les bonnes valeurs. Un second contexte avec une autre graine produit alors un motif différent mais tout aussi reproductible.

Les graines sont des valeurs de configuration ordinaires. Elles n'ont pas besoin d'être consécutives, et tout entier positif de la plage valide convient. Ce ne sont pas non plus des identifiants secrets : quiconque dispose du même build, du même profil et de la même graine peut reproduire le même motif de bruit, ce qui est précisément le but d'une configuration reproductible. Traitez-les comme le reste de la configuration de test, versionnez-les avec l'ensemble et tenez-les à l'écart des endroits où une réutilisation accidentelle est probable.

Gardez en tête la portée d'une graine. Des graines différentes donnent des motifs de bruit différents sur les mêmes valeurs de profil, ce qui n'équivaut pas à des navigateurs sans rapport entre eux. Les cookies, le stockage, la route réseau et le comportement de la personne ou du script qui utilise le navigateur sont des signaux distincts, et une graine n'en gère aucun.

Lancer avec une graine fixe

Le lancement déterministe le plus simple transmet un profil et une graine. Un répertoire de données utilisateur neuf écarte de la comparaison l'ancien état du navigateur :

chromium-browser \
  --bot-profile="path/to/profile.enc" \
  --bot-noise-seed=42 \
  --user-data-dir="$(mktemp -d)"

Quand les durées doivent aussi se répéter, ajoutez les contrôles indépendants de temps et de profondeur de pile avec leurs propres valeurs :

chromium-browser \
  --bot-profile="path/to/profile.enc" \
  --bot-noise-seed=42 \
  --bot-time-seed=42 \
  --bot-stack-seed=profile

Deux sessions simultanées qui doivent garder des identités différentes utilisent des graines différentes et des répertoires de données utilisateur séparés. La graine et le répertoire sont des contrôles distincts : la première fixe le motif de bruit, le second contient les cookies et le stockage.

chromium-browser --bot-profile="path/to/profile.enc" --bot-noise-seed=1001 --user-data-dir="tmp/session-a" &
chromium-browser --bot-profile="path/to/profile.enc" --bot-noise-seed=1002 --user-data-dir="tmp/session-b" &

Les frameworks d'automatisation transmettent les mêmes options comme arguments de lancement, à côté du chemin de l'exécutable du build BotBrowser. Définissez-les dans les arguments de lancement plutôt qu'après l'ouverture d'une page. La graine ne change pas la manière dont le framework pilote la page.

Il arrive que vous ayez besoin d'une sortie déterministe pour certaines surfaces et du rendu propre à la machine pour d'autres. Les interrupteurs par surface acceptent true ou false, et une surface que vous désactivez n'est plus régie par la graine :

chromium-browser \
  --bot-profile="path/to/profile.enc" \
  --bot-noise-seed=42 \
  --bot-noise-canvas=false \
  --bot-noise-audio-context=false

Considérez cette dernière forme comme une étape de diagnostic. Si le résultat d'un test cesse de se répéter, désactiver un canal à la fois montre quelle surface est en cause. Réactivez les canaux avant de vous appuyer sur la configuration, et gardez la commande de lancement finale dans vos notes pour pouvoir réutiliser les mêmes arguments. L'objectif est une seule ligne de commande que vous pouvez coller dans une seconde session en attendant le même comportement.

Vérifier la reproductibilité

La vérification n'a de sens que si la page testée est stable. Utilisez une page que vous maîtrisez, ou une page de test d'empreinte dont vous savez qu'elle dessine la même scène à chaque fois. Elle doit dessiner une scène Canvas fixe, relire une scène WebGL fixe, rendre un tampon audio hors ligne fixe et mesurer une chaîne fixe. Notez les valeurs qu'elle rapporte, ou un court condensé de chacune, pour que les comparaisons soient exactes. Exécutez la page de la même façon chaque fois, avec la même taille de fenêtre et le même ordre de chargement, afin que la seule différence voulue entre les exécutions soit la graine. Pour comprendre comment les différences d’AudioContext et d’OfflineAudioContext forment une empreinte audio et comment contrôler sa cohérence, consultez Empreinte audio expliquée : comment AudioContext vous piste.

  1. Lancez avec un profil et --bot-noise-seed=42, chargez la page et notez les valeurs de Canvas, WebGL, Audio et des métriques de texte.
  2. Fermez le navigateur, relancez avec le même profil et la même graine, puis chargez la même page. Toutes les valeurs notées doivent correspondre à la première exécution.
  3. Changez la graine en --bot-noise-seed=43 et exécutez la page une troisième fois. Les valeurs doivent différer de la première exécution, ce qui confirme que la graine façonne bien la sortie.
  4. Lancez deux fois avec --bot-noise-seed=0. La sortie doit varier entre ces sessions, car 0 garde le bruit actif sans graine déterministe.
  5. Conservez à côté des résultats le build BotBrowser, le fichier de profil, le système d'exploitation de la machine et la liste complète des arguments.

La dernière étape est celle que l'on omet souvent, et c'est elle qui rend facile l'explication d'un écart ultérieur. Un résultat n'est comparable à un autre que si le build, le profil, la graine et les arguments de lancement sont les mêmes.

Quand une seconde session ne correspond pas à la première, vérifiez le chemin et la version du profil, les arguments injectés par le framework et le contenu dessiné par la page. La documentation recommande aussi de garder stables le proxy, la langue, le fuseau horaire et la charge de la machine, car ces éléments peuvent modifier ce que fait une page même quand la graine n'a pas changé.

Répétez la routine chaque fois qu'une des entrées change : mise à jour de BotBrowser, remplacement d'un fichier de profil, changement de machine ou modification des arguments de lancement. Un court contrôle après chaque changement coûte moins cher que la découverte d'une dérive au milieu d'un long test, et il garde la cause d'une différence bien circonscrite, puisqu'une seule entrée a bougé.

Un enregistrement qui permet de reconstituer une session n'exige que quelques champs pour chaque graine :

  • La valeur de la graine et le compte ou le cas de test auquel elle appartient.
  • Le nom du fichier de profil et sa version.
  • Le build BotBrowser utilisé.
  • Le système d'exploitation cible de la machine et le type de machine.
  • La liste complète des arguments de lancement, y compris toute graine de temps ou de pile.
  • Les valeurs rapportées par la page de vérification, avec la date de l'exécution.

Avec cet enregistrement, une mise à jour devient une comparaison plutôt qu'une surprise. Exécutez la page de vérification sur le nouveau build avec la graine conservée et comparez-la aux valeurs conservées. Si elles correspondent, poursuivez. Si elles diffèrent, considérez les nouvelles valeurs comme une nouvelle référence, notez le build qui les a produites et ne modifiez pas la graine pour tenter de retrouver l'ancienne sortie, car la graine n'est jamais la partie qui a changé.

Parfois, un nouveau motif de bruit est exactement ce que vous voulez, par exemple quand vous retirez une identité de test pour en démarrer une autre. Changez la graine volontairement, mettez à jour l'enregistrement dans la foulée et gardez l'ancienne entrée avec son numéro de build. L'ancienne graine reste une description valable de ce que ce build a produit pour ce profil.

Ce type de vérification répond à une question étroite : ce build, avec ce profil et cette graine, répète-t-il son bruit ? Elle ne vous dit pas comment un site particulier réagit à l'empreinte. Gardez ces deux questions séparées dans vos notes.

Limites à prévoir

La reproductibilité est limitée au même build BotBrowser, au même profil et à la même valeur de --bot-noise-seed. L'algorithme de bruit peut changer entre versions majeures, donc une graine qui correspondait sur une version majeure doit être vérifiée de nouveau après une mise à jour. Une autre machine, un autre système d'exploitation cible ou d'autres arguments de lancement peuvent aussi modifier les résultats. Traitez une correspondance entre machines ou entre versions comme quelque chose à confirmer avec la routine ci-dessus, et non comme un acquis.

Une empreinte stable est aussi un compromis. Présenter la même sortie à chaque visite est ce qui fait fonctionner la continuité de session, et c'est la même propriété qui permet de reconnaître des visites répétées comme répétées. Si vous voulez que des sessions séparées portent des motifs de bruit sans rapport, donnez-leur des graines différentes, et n'oubliez pas que le motif de bruit n'est qu'un des signaux qu'un service peut observer. Une graine ne rend pas une empreinte impossible à relier, et rien ici ne dit comment un site réagira.

Il est aussi utile d'être précis sur ce qu'une vérification réussie vous permet d'affirmer. Elle vous permet de dire qu'un build, un profil et une graine ont répété la même sortie de Canvas, WebGL, Audio et des métriques de texte sur une machine donnée, et qu'une autre graine l'a changée. Elle ne permet pas de dire que le même résultat tiendra sur toutes les machines, après chaque mise à jour ou sur toutes les pages. Rédigez vos résultats sous la première forme, et l'enregistrement restera exact quand quelqu'un le relira des mois plus tard.

La graine 0 mérite une dernière mention, car on la choisit facilement par accident. Elle garde le bruit actif avec les valeurs par défaut du profil, ce qui est utile quand vous voulez de la variation, mais ce n'est pas un réglage déterministe. Si votre vérification montre une sortie qui change d'un lancement à l'autre, assurez-vous d'abord que la graine de la ligne de commande est un entier positif et que votre lanceur ou votre framework la transmet bien.

BotBrowser prend en charge --bot-noise-seed (ENT Tier2), un entier de 1 à 4294967295 qui initialise le bruit de Canvas, WebGL, Audio et des métriques de texte, de sorte que le même profil et la même graine répètent la même empreinte dans un test de continuité de session ou de vérification, tandis qu'une autre graine donne une identité stable distincte. BotBrowser ne peut pas garantir une sortie identique entre des builds, des profils ou des arguments de lancement différents, ne peut pas rendre une empreinte impossible à relier ni acceptée par un site, et ne remplace ni la gestion du stockage et des cookies, ni les choix de proxy et d'IP, ni les contrôles propres du site.

Pour le contexte sur les surfaces concernées, consultez Qu'est-ce que l'empreinte du navigateur, Empreinte Canvas, Protection de l'empreinte audio et l'aperçu plus court sur la reproductibilité de la graine de bruit.

Sources

Conclusion pratique

Conservez le profil, la graine positive, le build et tous les arguments dans chaque enregistrement. Répétez la fixture après chaque changement de build, de profil, de machine ou d’arguments, et limitez la conclusion au contexte déclaré.

#Deterministic#Noise-Seed#Reproducibility#fingerprinting#confidentialité

Cet article fait partie du guide : Qu'est-ce qu'une empreinte de navigateur ?

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.