Empreinte Canvas : fonctionnement et solutions
Comment le rendu Canvas devient un identifiant stable, pourquoi le VPN et la navigation privée ne le modifient pas et comment fonctionne une sortie déterministe pilotée par profil.
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.
BotBrowser peut rendre reproductible la lecture de Canvas dans un test autorisé avec un profil et une graine déclarés. Il ne garantit ni l’anonymat, ni l’acceptation par les sites, ni un rendu identique entre machines et piles graphiques.
TL;DR
L'empreinte Canvas vient des pixels rendus : effacer le stockage ou changer d'IP ne la modifie pas. Comparez un profil déclaré, --bot-noise-seed, l'écran, les polices et le backend graphique ; une sortie identique est un résultat Canvas limité, pas une preuve d'identité ni d'acceptation par un site.
Sommaire
- Ce que mesure l'empreinte Canvas
- Pourquoi le même dessin diffère d'un appareil à l'autre
- Pourquoi le VPN, la navigation privée et les extensions ne suffisent pas
- Quatre façons de traiter la sortie Canvas
- Comment BotBrowser traite Canvas
- Vérifier la stabilité et comprendre les écarts
Voir la démonstration contrôlée de Canvas
Cette vidéo en anglais compare un canvas synthétique avant et après la modification volontaire d’un octet. Elle illustre la comparaison des octets des pixels dans un environnement local contrôlé ; elle ne démontre ni l’identité d’un appareil ni les différences naturelles entre appareils.
L'élément Canvas de HTML5 existe pour dessiner. Graphiques, cartes, éditeurs d'images, zones de signature, jeux et tableaux de bord l'utilisent, ce qui en fait l'une des API web les plus répandues et une API sur laquelle les sites ordinaires s'appuient chaque jour.
Canvas a aussi un effet secondaire. Quand un navigateur dessine du texte ou des formes sur une toile, les pixels exacts dépendent du GPU de l'appareil, du pilote graphique, du rendu de texte du système d'exploitation, de la gestion des couleurs et du lissage des bords. Deux ordinateurs qui exécutent les mêmes instructions de dessin peuvent renvoyer des données de pixels légèrement différentes, alors qu'un même ordinateur renvoie les mêmes données à chaque fois. Cette répétabilité permet d'utiliser la sortie comme un signal pour reconnaître un navigateur.
La recherche sur le suivi a documenté cette pratique sur le web réel. Le Princeton Web Census, une mesure à grande échelle du million de sites web les plus visités, a trouvé des scripts d'empreinte Canvas sur plus de 14 000 d'entre eux. Ces chiffres appartiennent à cette étude et ne sont pas des mesures de BotBrowser.
L'empreinte Canvas ne demande aucune autorisation, ne stocke rien sur l'appareil et n'affiche rien au visiteur. Les navigateurs n'offrent aucun réglage intégré qui désactive le signal, et les pixels sont produits que le visiteur voie ou non un élément de la page, de sorte que le signal persiste tant que rien ne change la façon dont la sortie Canvas est produite. Les sections ci-dessous traitent de la manière dont le signal est produit, de la raison pour laquelle les outils de confidentialité courants ne le modifient pas, des différentes façons de traiter la sortie Canvas et de la manière de vérifier que la sortie est stable pendant un test autorisé.
Ce que mesure l'empreinte Canvas
Un script d'empreinte ne s'intéresse pas à l'image elle-même. Un flux de collecte typique comporte cinq étapes courtes :
- Un script s'exécute dans la page ou dans un cadre intégré, souvent fourni avec un composant publicitaire ou d'analyse.
- Il crée une toile et dessine un motif de test fixe : du texte dans plusieurs polices, des dégradés, des formes qui se chevauchent et des couleurs semi-transparentes.
- Il relit les pixels avec
toDataURLougetImageData. - Il condense les données de pixels en une courte valeur de synthèse.
- Il envoie cette valeur à un serveur avec d'autres signaux du navigateur, où elle est comparée aux visites précédentes.
La valeur de synthèse est utile à un traceur pour trois raisons. Elle ne change pas quand on efface les cookies, elle ne change pas derrière une autre adresse IP et elle coûte peu à collecter sur n'importe quelle page. Un site qui revoit la même valeur peut relier les visites, et un traceur présent sur de nombreux sites peut relier des visites sur des domaines sans rapport.
Canvas est rarement utilisé seul. Les scripts le combinent avec des détails du moteur de rendu WebGL, les polices installées, les propriétés d'écran, le fuseau horaire et la langue. Pris ensemble, des signaux que beaucoup de navigateurs partagent chacun peuvent pourtant distinguer un appareil. Canvas apporte la part qui vient du chemin de rendu graphique et textuel, et cette part est difficile à modifier en changeant d'autres réglages.
Relire des pixels est aussi une opération normale. Les graphiques, les éditeurs de photos, la capture de signature et certains CAPTCHA lisent des pixels pour des raisons ordinaires, si bien que l'appel seul n'est pas suspect. Ce qui pose problème, c'est un motif de test caché dont le seul but est de produire un identifiant. La documentation de l'API Canvas sur MDN et la section canvas de la norme HTML décrivent l'interface elle-même, et toutes deux figurent dans les sources publiques ci-dessous.
Les personnes qui auditent un site à la recherche d'empreintes cherchent en général une forme reconnaissable plutôt qu'un seul appel d'API. Une toile créée mais jamais rattachée à la page, une petite taille fixe, une phrase qui emploie beaucoup de lettres différentes, des formes colorées qui se chevauchent et une relecture immédiate suivie d'un envoi réseau en sont les signes typiques. Aucun de ces signes ne prouve à lui seul une intention, et un graphique légitime peut en partager certains, de sorte que le relecteur les pèse avec ce que le script fait du résultat.
Pourquoi le même dessin diffère d'un appareil à l'autre
Pour une comparaison reproductible, notez la recette de dessin : width et height du canevas, la chaîne et la police de fillText(), puis les octets de getImageData(0, 0, width, height). Modifier l'une de ces entrées ne prouve pas que la pile graphique a changé.
Les spécifications décrivent ce que signifie un appel de dessin, pas la valeur exacte de chaque pixel de sortie, si bien que chaque plateforme a de la marge pour différer. En pratique, plusieurs couches du chemin de rendu y contribuent :
- Rastérisation des polices. Windows, macOS et Linux utilisent chacun leur propre pile de rendu du texte, avec des formes de glyphes, un hinting et un lissage des bords différents.
- GPU et pilote. Les dégradés, le mélange et la composition passent par du matériel graphique et des pilotes qui peuvent différer sur les derniers bits de chaque canal de couleur.
- Gestion des couleurs. Les systèmes d'exploitation appliquent des profils de couleur et un traitement du gamma différents, ce qui décale les valeurs à l'intérieur des dégradés et des formes translucides.
- Anticrénelage. Le lissage des bords varie selon la plateforme, la version du pilote et les réglages système. Les différences sont invisibles à l'œil nu mais présentes dans les données de pixels.
- Calcul en virgule flottante. Les courbes et les opérations géométriques peuvent s'arrondir différemment selon le matériel, ce qui modifie quelques pixels le long des bords.
Les polices ajoutent une couche de plus. Quand un script demande une police qui n'est pas installée, la plateforme se rabat sur une police par défaut, et ce choix dépend du système d'exploitation et de ses polices installées. Le même texte dessiné avec le même nom de police peut donc produire des glyphes différents sur deux systèmes, ce qui explique que les polices soient traitées comme une surface d'empreinte à part entière.
Chaque différence est minuscule, mais une empreinte n'a besoin que d'un pixel différent. La combinaison est stable sur une même machine et varie d'une machine à l'autre. Elle survit aussi au redémarrage du navigateur, à l'effacement du cache ou à l'ouverture d'une fenêtre privée, car aucune de ces actions ne change la pile graphique sous-jacente.
Le même raisonnement vaut en sens inverse. Deux machines ayant la même version du système d'exploitation, le même GPU, le même pilote et les mêmes polices peuvent renvoyer une sortie identique, si bien que Canvas seul restreint le champ au lieu de désigner un seul appareil. C'est pourquoi les traceurs l'associent à d'autres signaux, et pourquoi une défense qui ne regarde que Canvas laisse intact le reste de la combinaison.
C'est pourquoi Canvas est étroitement lié au reste du profil d'un appareil. Un navigateur qui annonce un GPU Apple et un agent utilisateur Mac tout en produisant une sortie Canvas typique du rendu de texte de Linux est incohérent en interne, et la cohérence entre signaux est précisément ce que regarde quiconque analyse des empreintes.
Pourquoi le VPN, la navigation privée et les extensions ne suffisent pas
La limite est visible dans les API : un VPN modifie les adresses exposées à RTCPeerConnection ou HTTP, tandis que l'identification Canvas lit les pixels avec getImageData() ou toDataURL(). Effacer localStorage ou les cookies modifie l'état stocké, pas le bitmap retourné par ces appels.
Chaque outil de confidentialité courant agit sur une couche différente de celle dont Canvas tire ses données.
VPN et proxys. Un VPN ou un proxy change l'adresse réseau que voit un site. La sortie Canvas est produite dans le navigateur à partir du rendu local et ne transite jamais par le chemin réseau, de sorte que deux appareils derrière le même VPN renvoient chacun leur propre sortie Canvas.
Navigation privée. Les fenêtres privées suppriment les cookies, l'historique et le stockage du site à la fin de la session. Elles ne changent pas le chemin de rendu, donc la sortie Canvas dans une fenêtre privée est la même que dans une fenêtre normale. Le guide sur la navigation privée précise ce que ces modes changent et ne changent pas.
Extensions qui bloquent Canvas. Bloquer la relecture fait échouer les appels ou renvoyer des données vides. Très peu de navigateurs réels se comportent ainsi, si bien que le blocage lui-même peut se remarquer, et les pages qui utilisent Canvas à des fins légitimes peuvent cesser de fonctionner.
Extensions qui ajoutent du bruit aléatoire. Le bruit aléatoire produit une nouvelle valeur à chaque chargement. Cela empêche un identifiant stable, mais une valeur qui change à chaque visite est elle aussi inhabituelle, et le bruit ajouté au niveau des scripts peut ne pas ressembler à la variation naturelle entre appareils réels.
Extensions qui renvoient de fausses données. Les pixels de remplacement peuvent casser les graphiques, les cartes et les CAPTCHA, et ils sont souvent en désaccord avec le GPU, les polices et le système d'exploitation que le même navigateur annonce par ailleurs.
Randomisation intégrée. Certains navigateurs, dont Brave, ajoutent de petites variations aléatoires à la sortie Canvas selon le site. C'est mieux que le blocage, mais le résultat peut encore ne pas concorder avec les signaux de GPU, de polices et de système d'exploitation annoncés par le même navigateur, et chaque implémentation décide quelles opérations Canvas elle couvre.
Résultats inégaux selon les outils. Aucun outil ne change toutes les couches. Un VPN change l'adresse réseau mais pas les pixels, la navigation privée change le stockage mais pas les pixels, et une extension change ce que voit un script sans changer la manière dont la page est rendue. Chacun répond à une préoccupation et laisse le signal Canvas tel quel, ce qui explique qu'une réponse durable doive s'attaquer aux pixels eux-mêmes.
Demandes d'autorisation. Tor Browser demande avant qu'un site puisse lire les données d'image de Canvas. Cela rend la relecture visible, mais laisse la décision au visiteur, et une demande refusée peut casser la page qui l'a faite.
Quatre façons de traiter la sortie Canvas
Documentez le choix avec les deux contrôles qui le déterminent : --bot-noise-canvas=true active la politique de rendu et --bot-noise-seed=42 fixe un motif de bruit reproductible. Ne comparez pas une exécution sans seed déclaré à une exécution avec seed fixe.
Les approches se distinguent par ce qu'elles sacrifient. Deux questions facilitent la comparaison : la sortie reste-t-elle stable pour une même configuration, et reste-t-elle cohérente avec tout ce que le navigateur annonce par ailleurs ?
- Blocage. La sortie est stable car elle est toujours vide, mais elle est incohérente avec un navigateur normal et risque de casser les pages qui ont besoin de Canvas.
- Bruit aléatoire. La sortie diffère à chaque chargement ou à chaque origine. Cela limite le rapprochement dans le périmètre du bruit, mais ne donne aucun résultat répétable pour les tests et peut ne pas correspondre aux autres signaux.
- Fausses données. Une valeur de remplacement fixe est répétable, mais elle n'a aucun rapport avec ce que la page a réellement dessiné, de sorte que les fonctions qui dépendent du dessin et les autres signaux peuvent la contredire.
- Sortie déterministe pilotée par profil. La sortie Canvas suit le profil chargé et une graine de bruit fixe, de sorte que le même profil et la même graine donnent toujours le même résultat, tandis qu'un autre profil ou une autre graine en donne un différent.
La dernière option compte pour les tests autorisés et la recherche sur la confidentialité, car elle rend le comportement de Canvas reproductible. Si un test montre un changement de sortie, la cause est le profil ou la graine qui a été modifié, et non un bruit résiduel d'une exécution précédente.
L'option adaptée dépend de l'objectif. Le blocage convient à un environnement de lecture très restreint où des pages cassées sont acceptables. Le bruit aléatoire convient à la navigation quotidienne dont le seul but est d'éviter d'être relié d'un site à l'autre. La sortie déterministe convient aux travaux où un résultat doit être répété et expliqué, comme les contrôles de non-régression sur un site que vous exploitez ou la recherche qui compare une configuration à une autre.
Le déterminisme ne fait pas disparaître le signal. Canvas n'est qu'un signal parmi d'autres, et une valeur stable qui contredit WebGL, les polices, le fuseau horaire, les paramètres régionaux ou la localisation réseau peut encore sembler incohérente. C'est pourquoi les vérifications de la dernière section dépassent le seul Canvas.
Comment BotBrowser traite Canvas
La documentation Canvas de BotBrowser décrit une protection pilotée par profil pour la relecture de Canvas. Quand un profil est chargé, BotBrowser applique un bruit déterministe à la sortie Canvas 2D au niveau du rendu plutôt que par injection de JavaScript, et la documentation indique que cela couvre la relecture de pixels et la mesure du texte. Quatre comportements documentés comptent pour le scénario ci-dessus :
- Le bruit Canvas est activé par défaut et peut être défini explicitement avec
--bot-noise-canvas=trueou--bot-noise-canvas=false. --bot-noise-seedsélectionne un motif de bruit précis et reproductible. Chaque graine produit une sortie Canvas unique mais stable, et la même graine s'applique aussi à d'autres surfaces comme WebGL, WebGPU et les métriques de texte.- Avec un profil chargé, BotBrowser utilise ses bibliothèques de polices intégrées et son rendu pour comparer la sortie Canvas entre hôtes dans les conditions documentées de profil, graine, écran et graphiques ; il ne garantit pas une sortie identique sur tous les hôtes ou toutes les piles graphiques.
- BotBrowser 150 maintient la protection de Canvas 2D active pour les espaces colorimétriques standard et à large gamme, y compris
display-p3.
Un lancement minimal qui fixe à la fois le profil et la graine ressemble à ceci :
chromium-browser --bot-profile="path/to/profile.enc" --bot-noise-seed=42
Comme chaque graine donne un résultat stable qui lui est propre, une équipe qui exécute plusieurs sessions peut attribuer à chacune sa propre graine. Les sessions restent alors distinctes les unes des autres tout en se répétant à l'identique quand une graine est réutilisée, ce qui est la propriété dont un test de non-régression a besoin.
Gardez la configuration simple. Un second outil qui modifie lui aussi la sortie Canvas, comme une extension, rend les résultats plus difficiles à interpréter, car deux couches façonnent alors les mêmes pixels.
Pour la revue, la documentation de CanvasLab décrit l'enregistrement, avec --bot-canvas-record-file, des appels Canvas 2D, WebGL, WebGL2 et WebGPU qu'effectue une page, afin qu'une équipe voie ce qu'une page dessine et lit réellement avant de décider quoi tester.
Vérifier la stabilité et comprendre les écarts
Une vérification utile comporte trois étapes et ne demande aucun code de collecte spécifique. Ne l'exécutez que sur des pages et des systèmes que vous êtes autorisé à tester.
- Lancez avec un profil et un
--bot-noise-seedfixe, ouvrez une page publique de test d'empreintes et notez la sortie Canvas indiquée. - Rechargez, puis fermez et redémarrez la session avec le même profil et la même graine. La sortie doit correspondre à celle de la première exécution.
- Changez la graine ou le profil. La sortie doit changer.
Gardez le périmètre d'un test étroit et documenté. Utilisez des pages qui vous appartiennent ou pour lesquelles vous avez une autorisation écrite, et ne traitez le résultat que comme une preuve sur la sortie Canvas, non comme un verdict sur une autre surface d'empreinte ni sur la réaction d'un site particulier.
Notez la configuration à côté de chaque résultat. La version de BotBrowser, le fichier de profil, la valeur de la graine, le système d'exploitation hôte et le caractère sans interface ou avec interface de l'exécution suffisent pour qu'une exécution ultérieure soit comparée équitablement. Sans cette trace, un écart entre deux exécutions ne peut pas être rattaché à une cause.
Quand le résultat n'est pas celui attendu, la documentation de BotBrowser indique une courte liste de causes :
- La sortie change d'une session à l'autre avec le même profil. Sans graine fixe, le bruit varie par session par conception, donc confirmez la même valeur de
--bot-noise-seed. - La sortie diffère entre les exécutions sans interface et avec interface. Confirmez
--bot-noise-canvas=trueet le même profil dans les deux. - La sortie ressemble à la sortie brute du système. Confirmez que le profil s'est bien chargé et lisez les messages de démarrage.
- La sortie diffère sur un autre système d'exploitation hôte. Vérifiez le profil, la graine, l'écran, le backend graphique et les polices avant d'interpréter l'écart ; un profil rend la comparaison reproductible, mais ne garantit pas une sortie identique sur tous les hôtes.
- Canvas à large gamme se comporte autrement que Canvas standard. Utilisez BotBrowser 150.0.7871.46 ou une version plus récente avec un paquet de profil correspondant.
Lisez le premier résultat avec prudence. Une seule exécution montre seulement que la sortie existe. C'est la comparaison entre rechargements, redémarrages, graines et profils qui montre si la sortie se comporte comme prévu, et l'absence de changement à l'étape trois est aussi instructive qu'un écart à l'étape deux.
Vérifiez ensuite ce que Canvas ne couvre pas. Comparez les valeurs du moteur de rendu WebGL, les polices installées, le fuseau horaire, les paramètres régionaux et la localisation réseau avec le même profil, car un résultat Canvas stable à côté d'un fuseau horaire ou d'une langue qui contredit le profil donne encore une image incohérente. Les articles sur l'empreinte WebGL, l'empreinte des polices et la reproductibilité de la graine de bruit traitent de ces signaux voisins.
BotBrowser applique un bruit déterministe Canvas 2D piloté par le profil au niveau du rendu, reproductible avec --bot-noise-seed dans des conditions déclarées, afin qu'une équipe compare les lectures Canvas dans le scénario de tests autorisés et de recherche sur la confidentialité décrit ici. BotBrowser ne peut garantir ni l'anonymat ni qu'un site n'identifiera, ne suivra ou ne bloquera le visiteur ; il ne contrôle pas non plus les scripts de collecte Canvas ni le regroupement d'appareils côté serveur. La reproductibilité entre hôtes exige de garder constants le profil, la graine, l'écran, le backend graphique et les polices, sans impliquer que toutes les piles graphiques produisent une sortie identique. Cela ne remplace pas la cohérence des signaux WebGL, des polices, du fuseau horaire, des paramètres régionaux et du proxy avec le même profil.
Pour approfondir, consultez Fingerprinting par mesure de texte : suivi sous-pixel.
Conclusion pratique
Pour une comparaison autorisée, figez la recette de dessin et notez le profil, --bot-noise-seed, l'écran, les polices et le backend graphique avec la lecture de pixels. Un écart inattendu est d'abord une question de configuration ; ni un digest stable ni un digest différent ne prouvent l'anonymat ou la décision d'un site distant.
Sources publiques
Cet article fait partie du guide : Qu'est-ce qu'une empreinte de navigateur ?
Articles Connexes
Empreinte audio expliquée : comment AudioContext vous piste
EmpreinteMode déterministe : empreintes reproductibles
EmpreinteFingerprinting par mesure de texte : suivi sous-pixel
Empreintewebgl_debug_renderer_info : ce que votre GPU révèle aux pages
EmpreinteQu'est-ce qu'une empreinte de navigateur ?
Empreinteperformance.now : résolution et fingerprinting
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.