Retour au Centre de connaissances
Empreinte

Rapport WebGL de CreepJS : contextes et signaux

Suivez les champs WebGL de CreepJS depuis le code source épinglé : contextes, renderer, lecture des pixels et limites.

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.

Un rapport WebGL de CreepJS ne correspond ni à une valeur graphique unique ni à un seul test réussi ou échoué. Dans l'implémentation publique épinglée, des chemins de code distincts recueillent les paramètres WebGL et WebGL2, des métadonnées renderer facultatives, la précision des shaders, les données d'image du canvas et des résumés de capacité dérivés. Lire tous ces champs comme un verdict unique masque l'opération qui a produit chacun d'eux et le chemin d'échec réellement suivi.

BotBrowser documente le comportement WebGL piloté par les profils et sa vérification, mais ne prétend pas qu'un rapport CreepJS identifie un appareil physique ni qu'il prédit la décision d'un site tiers. La tâche utile est plus précise : suivre une implémentation identifiée depuis ses champs sources jusqu'à ses branches conditionnelles de rapport, puis conserver les limites propres à chaque observation.

BotBrowser permet la configuration WebGL par profil et des vérifications autorisées du comportement déclaré ; il ne peut pas établir l'identité d'un appareil physique ni la décision d'un autre site à partir d'un champ CreepJS.

Pour le collecteur distinct de BrowserLeaks, l'analyse de son rapport WebGL suit la découverte du contexte, les données renderer facultatives et les contrôles de champs absents, sans attribuer ces résultats à CreepJS.

TL;DR

  • Le fichier examiné est src/webgl/index.ts du commit CreepJS 10aa6724cd33a1015db1574211890518cd04f0cc. La lecture statique ne démontre ni le comportement actuel du site ni une mesure BotBrowser.
  • La fonction crée séparément des contextes WebGL et WebGL2. Elle s'arrête si le contexte WebGL manque, mais la branche visible n'exige pas que le contexte WebGL2 soit disponible pour continuer.
  • La comparaison miroir vérifie certaines valeurs du tableau de paramètres WebGL2 par rapport aux valeurs vraies du tableau WebGL. Elle ignore ALIASED_LINE_WIDTH_RANGE, SHADING_LANGUAGE_VERSION et VERSION.
  • WEBGL_debug_renderer_info, la précision des shaders, un URI de données canvas et le résultat de readPixels sont des observations distinctes. L'absence de données dans une voie n'explique pas une autre voie.
  • Une branche dérivée des capacités peut définir LowerEntropy.WEBGL lorsqu'une valeur ne figure pas dans une liste intégrée. C'est le comportement de cette implémentation épinglée, pas une règle WebGL universelle ni une affirmation sur une personne.

Sommaire

Des voies distinctes montrent les contextes WebGL, la comparaison des paramètres, le renderer facultatif, l'export canvas, la lecture des pixels et les capacités dérivées.

Deux contextes lancent des voies de collecte distinctes

Le code crée un canvas pour le contexte webgl et un autre pour webgl2, puis appelle getContext avec les noms correspondants. La fonction vérifie si le premier contexte existe. Dans le cas contraire, CreepJS enregistre un résultat de test webgl en échec et quitte cette voie. À cet endroit, le code ne comporte pas de retour anticipé équivalent pour gl2 ; les helpers ultérieurs traitent un contexte absent autrement.

Cet ordre compte lors de la lecture d'un rapport compact. L'échec de la voie WebGL ne signifie pas que les deux types de contexte ont été testés avec succès et ont renvoyé des résultats identiques. Le code n'explique pas non plus pourquoi le premier contexte était indisponible. La création peut dépendre de la prise en charge du navigateur, de l'état du canvas, des conditions de ressources et du code de l'application. Le champ du rapport ne désigne pas l'explication applicable.

Cette distinction est utile sur une page de diagnostic que l'application maîtrise. Un collecteur peut enregistrer webgl_context_created et webgl2_context_created séparément, puis préserver à part une erreur si la configuration déclenche une exception. Il ne devrait pas écrire un seul booléen graphics_supported avant que chaque tentative ait un résultat défini. Ce schéma de journalisation proposé aide à lire le code côté application ; ce n'est ni un schéma de sortie CreepJS ni une API normalisée du navigateur.

Événement de collecteCe que le code épinglé établitCe qui reste inconnu
Le contexte WebGL est absentCette fonction enregistre un échec du test webgl et arrête cette voiePourquoi la demande n'a pas produit de contexte ou si une nouvelle tentative changerait le résultat
WebGL existe ; WebGL2 manqueLa voie dépasse le premier contrôle ; les helpers recevant un contexte absent peuvent renvoyer des données vides ou indéfiniesSi les champs ultérieurs du rapport conservent cette distinction pour un consommateur donné
Les deux références de contexte existentLes helpers suivants de paramètres et de rendu peuvent recevoir les deux référencesSi chaque extension facultative et chaque lecture réussira
La configuration échoue avant l'affectation d'un champLa gestion d'erreur externe peut renvoyer un résultat ayant la forme d'une erreurQuelle opération a échoué, sauf si son étape est conservée avec l'erreur

Il s'agit d'une carte du flux de contrôle, pas d'une matrice de compatibilité. La disponibilité d'un contexte n'implique pas que toutes les extensions facultatives existent, et sa création réussie ne garantit pas que le buffer de dessin soit lisible. Une application qui compare des versions de navigateur devrait indiquer séparément le contexte demandé, le résultat de l'appel et chaque opération ultérieure. Un changement du code de collecte reste ainsi visible au lieu de se faire passer pour une différence de capacité graphique.

La présentation du fingerprinting WebGL couvre la surface de divulgation plus générale et les contrôles de profil BotBrowser. Le module épinglé src/webgl/index.ts construit séparément les résultats de contexte, les comparaisons de paramètres, les métadonnées renderer facultatives, la précision des shaders, les sorties canvas et pixels, ainsi que les champs de capacité dérivée. L'analyse des absences de renderer WebGL décrit des états côté application tels qu'un champ non demandé, un contexte indisponible ou perdu et une extension indisponible ; elle ne suit pas l'assemblage de sortie CreepJS.

La comparaison miroir a une couverture conditionnelle

Après avoir construit des objets de paramètres pour les deux contextes, l'implémentation définit trois clés exclues de la comparaison miroir : ALIASED_LINE_WIDTH_RANGE, SHADING_LANGUAGE_VERSION et VERSION. La liste des divergences est formée à partir des clés de l'objet WebGL2. Pour rester candidate, une clé doit aussi avoir une valeur vraie dans l'objet WebGL, ne pas faire partie des noms exclus et avoir une représentation sous forme de chaîne différente dans les deux objets. La branche de rapport ne s'exécute que si la liste obtenue n'est pas vide.

La condition peut se représenter sans lui attribuer une portée excessive :

pour chaque clé de l'objet de paramètres WebGL2 :
  la garder uniquement si WebGL[key] est vraie
  ignorer ALIASED_LINE_WIDTH_RANGE, SHADING_LANGUAGE_VERSION, VERSION
  comparer String(WebGL[key]) à String(WebGL2[key])
signaler une divergence uniquement s'il reste au moins une clé

Cette lecture du code est utile parce qu'elle montre à la fois la couverture et ses omissions. Il ne s'agit pas d'une assertion exhaustive d'égalité sur toutes les valeurs exposées par les deux contextes. Une propriété présente uniquement dans l'objet WebGL n'est pas parcourue. Une valeur WebGL fausse ne franchit pas le filtre de vérité. Une différence masquée par la conversion en chaîne peut être traitée autrement qu'une comparaison structurelle de tableaux ou de valeurs typées. Les trois noms exclus restent hors de cette vérification, quelle que soit leur valeur.

Forme d'entrée illustrativeIncluse dans la liste de divergence du code ?Motif
Même valeur vraie pour une clé non exclue dans les deux tableauxNonLes représentations sous forme de chaîne sont identiques
Valeurs vraies différentes pour une clé non exclue présente dans les deux tableauxOuiLes représentations sous forme de chaîne diffèrent
Valeur WebGL égale à 0, false, '', null ou undefinedNonLe filtre exige une valeur vraie côté WebGL
Clé absente de l'objet WebGL2NonL'implémentation parcourt les clés WebGL2
Clé égale à VERSION ou à l'un des deux autres noms exclusNonLa table d'exclusion explicite la filtre

Ces cas décrivent le prédicat visible dans le code épinglé ; ils n'affirment pas ce qu'a renvoyé un navigateur donné. Le raisonnement peut être reproduit en examinant l'objet VersionParam, le filtre sur Object.keys(params2) et la condition mismatch.length dans le commit référencé. La distinction évite une extrapolation fréquente : « le rapport n'indique aucune divergence » ne signifie pas que toutes les sorties WebGL et WebGL2 étaient égales. Cela signifie uniquement que ce prédicat a produit une liste vide pour les données reçues.

Le rapport n'indique pas non plus à une équipe de maintenance si une divergence vient d'un défaut d'implémentation, de valeurs non prises en charge, de la sérialisation, d'un contexte manquant ou d'un changement de collecte. Ce sont des pistes d'investigation possibles, pas des conclusions contenues dans la branche. Un relevé de diagnostic doit préserver le nom du champ et l'étape de collecte lorsque la cause importe ; un total agrégé de « divergences WebGL » élimine justement les éléments nécessaires pour distinguer ces cas.

Les champs renderer et précision ne sont pas interchangeables

Le code recueille d'abord les valeurs des paramètres de chaque contexte. Il ajoute ensuite des informations renderer non masquées si WEBGL_debug_renderer_info est disponible. Le helper demande cette extension au contexte ; si elle est absente, il renvoie un objet vide. Si elle est disponible, il lit UNMASKED_VENDOR_WEBGL et UNMASKED_RENDERER_WEBGL au moyen de getParameter.

Cette voie d'extension facultative est distincte des paramètres ordinaires du contexte. La spécification d'extension de Khronos définit les constantes facultatives du vendor et du renderer non masqués ; la référence MDN getParameter décrit l'API de requête. Aucune de ces sources ne fait de l'absence de l'objet d'extension une explication causale. Elle ne prouve ni un réglage de confidentialité, ni l'absence de GPU, ni une décision de politique, ni l'intention de l'application. Cela signifie que le helper n'a pas ajouté ces deux champs par cette voie.

La précision des shaders constitue une autre catégorie. Le helper demande plusieurs formats pour les shaders de sommets et de fragments, notamment les précisions flottantes faible, moyenne et haute, ainsi qu'une précision entière élevée. Il écrit ensuite les propriétés precision, rangeMax et rangeMin sous des clés associées à l'étape du shader et au format. Ces champs décrivent le résultat renvoyé par la requête de précision sur le contexte courant. Ce ne sont ni des noms de renderer, ni des indicateurs d'extension, ni la preuve que deux appareils sont physiquement identiques.

L'objet final de paramètres ajoute aussi certains attributs et limites du contexte. L'assemblage visible inclut l'attribut antialias, MAX_VIEWPORT_DIMS, l'anisotropie de texture maximale lorsqu'une extension d'anisotropie est trouvée, et MAX_DRAW_BUFFERS_WEBGL lorsque son extension est disponible. Plusieurs requêtes sont enveloppées dans un helper attempt, tandis que les valeurs dépendantes d'extensions peuvent manquer. Le consommateur du rapport devrait donc séparer « absent », « non demandé » et « erreur de requête » lorsque la sortie qui les entoure préserve cette distinction.

Famille de sortieOpération sourceCe qu'une valeur absente ne permet pas d'établir
Paramètres standardÉnumérer les noms de paramètres sélectionnés et appeler getParameterQue le navigateur n'ait aucune capacité graphique
Vendor/renderer non masquésDemander WEBGL_debug_renderer_info, puis lire deux constantesQu'un réglage de confidentialité a causé l'absence
Précision des shadersAppeler getShaderPrecisionFormat pour des formats nommésUne identité d'appareil stable ou un verdict de site
Limites facultativesDemander des constantes dépendantes d'extensions ou des attributs du contexteSi une autre requête indépendante réussirait

Ce tableau décrit volontairement le chemin du code, pas un schéma de suivi recommandé. Les chaînes renderer peuvent être identifiantes et ne sont pas toujours nécessaires pour répondre à une demande de support. Un produit devrait collecter uniquement ce dont sa tâche annoncée a besoin, expliquer les diagnostics facultatifs et éviter de transformer une étiquette brute en clé de compte. La documentation WebGL de BotBrowser décrit les réglages propres à BotBrowser pilotés par profil ; le code CreepJS ne prouve pas qu'une valeur précise soit renvoyée sur la machine d'une personne.

L'export du canvas et la lecture des pixels peuvent diverger

Le helper getWebGLData dessine un motif dans un contexte et tente de produire deux familles de sorties. L'une est un URI de données canvas. L'autre est un tableau d'octets rempli par readPixels. Le code lit les dimensions du buffer de dessin, calcule une largeur et une hauteur réduites en divisant par 15 et 6, alloue quatre octets par pixel échantillonné, puis demande des valeurs RGBA non signées de huit bits depuis l'origine en bas à gauche.

Cet ordre crée un cas concret d'échec partiel. La fonction tente toDataURL avant readPixels. Si l'appel interne à readPixels lève une exception, le catch renvoie le dataURI déjà obtenu et définit pixels à undefined. Le résultat n'est donc pas tout ou rien. Si une image apparaît avec des données de pixels absentes, cela ne prouve pas que toute la voie WebGL ait échoué. À l'inverse, l'absence d'URI de données ne prouve pas qu'une lecture de pixels a été tentée : une erreur antérieure peut atteindre d'abord le catch externe.

Le helper traite également un OffscreenCanvas de manière particulière : il crée un canvas ordinaire pour l'opération d'URI de données et y dessine. La lecture des pixels reste liée au contexte WebGL d'origine. Le chemin d'export d'image et le chemin des pixels sont donc reliés par le dessin, sans être le même appel d'API ni la même représentation de sortie.

Point d'échecVoie URI de donnéesVoie pixelsLimite de lecture
L'argument de contexte manqueLe helper renvoie des champs de sortie indéfinisAucune lecture n'a lieuCe helper n'explique pas pourquoi le contexte manque
Le dessin ou la création de l'URI échoueLa gestion externe capture une erreurLa lecture suivante n'est pas atteinteNe pas classer cela comme un échec de readPixels
readPixels échoue après la création d'un URILe helper peut renvoyer le data URIpixels devient undefinedLes deux champs n'ont pas un indicateur de réussite atomique commun
Les deux opérations renvoient un résultatL'URI de données est présentUn tableau de pixels est renvoyéAucune de ces valeurs ne décrit à elle seule un appareil physique

Une personne qui maintient une page de rendu peut utiliser cette carte pour écrire un test de support : noter si le dessin a été exécuté, si la sérialisation s'est terminée et si la lecture des pixels s'est terminée. Garder les sorties séparées permet d'évaluer un mode de repli sans conserver plus de données que ne l'exige la question de support. Il n'est pas affirmé que la grille échantillonnée soit une empreinte standardisée ou unique, ni que l'une de ces sorties prédise l'acceptation d'une session par un tiers.

Les résumés de capacités sont calculés plus tard

Après la collecte des champs sources, le module crée une liste numérique normalisée à partir des valeurs de premier niveau qui sont truthy en JavaScript et ne sont pas des chaînes. Array.prototype.flat() aplatit les tableaux sur un niveau ; chaque élément obtenu est converti avec Number, les doublons sont supprimés et le résultat est trié numériquement. Le code utilise ensuite la chaîne renderer pour déduire une marque GPU et calcule deux résumés distincts : une valeur compacte issue de la marque et du vecteur de paramètres, et une valeur de capacité fondée sur une réduction de la liste numérique.

Le module compare ces valeurs dérivées à des listes intégrées. Si une valeur marque-capacités existe mais manque dans la liste des marques, la condition hasSusGpu est vraie. Si la valeur de capacité dérivée existe mais ne figure pas dans la liste numérique, hasSusCapabilities est vraie. Chacune de ces branches peut définir LowerEntropy.WEBGL et appeler sendToTrash avec une étiquette correspondante. Le code enregistre ensuite le test WebGL comme réussi et renvoie les données recueillies avec des champs de classification GPU.

Le mot « suspicious » d'un nom de variable appartient à la branche interne de l'implémentation. Ce n'est pas une définition standard du matériel suspect. Une valeur hors liste peut venir d'une modification de la liste, d'une combinaison non représentée, d'un paramètre absent ou modifié, ou de l'environnement d'exécution. La lecture statique du code ne peut pas dire laquelle de ces possibilités décrit actuellement un navigateur donné.

Élément dérivéEntrées visibles dans le codeCe que la branche ne prouve pas
webglParamsValeurs truthy de premier niveau qui ne sont pas des chaînes ; tableaux aplatis sur un niveau, convertis, dédupliqués et triésQue tous les paramètres WebGL soient présents ou que le vecteur soit stable entre versions
webglBrandCapabilitiesUne marque dérivée du renderer et la forme textuelle du vecteur de paramètresQue la chaîne renderer nomme un matériel physique ou que la valeur identifie un appareil de façon unique
webglCapabilitiesValeurs numériques des paramètres et leurs positions triées dans une réductionQue le résultat soit un identifiant de capacité reconnu par le secteur
Branche LowerEntropy.WEBGLTests d'appartenance aux tableaux de marques et de capacités intégrésUn verdict universel de bot, l'identité d'un compte ou la cause d'une politique

Il existe une différence importante entre les champs bruts et un résumé dérivé. Un champ brut se rattache à un appel de l'API WebGL. Un résumé peut dépendre de la normalisation, du tri, de fonctions de valeur compacte, de listes de consultation et de contrôles de vérité après la collecte. Si le rapport final change, il est préférable de comparer d'abord la révision du code source et ces transformations plutôt que d'attribuer le changement à un GPU physique.

L'analyse des groupes de signaux CreepJS explique comment un rapport regroupe des surfaces indépendantes du navigateur. L'analyse des décisions entre groupes couvre les combinaisons et la logique de décision. La branche dérivée du module utilise ses champs WebGL collectés et ses listes intégrées ; elle ne décrit pas à elle seule l'agrégation entre groupes.

La lecture du rapport doit respecter les limites de preuve

Une revue disciplinée du code commence par figer la révision. Le même chemin sur une branche principale évolutive peut changer entre un rapport enregistré et aujourd'hui. Épingler le commit 10aa6724cd33a1015db1574211890518cd04f0cc et le chemin src/webgl/index.ts rend les références aux lignes et les descriptions du flux de contrôle reproductibles. Cela ne prouve toujours pas qu'un site actif a déployé cette révision, qu'un rapport donné a été produit avec elle, ni que chaque branche a été exécutée dans un navigateur particulier.

Pour examiner un rapport, consignez uniquement les faits nécessaires à la question :

  1. Identifiez le champ affiché et sa famille de sortie : contexte, paramètre, extension facultative, requête shader, URI de données, tableau de pixels ou résumé dérivé.
  2. Reliez le champ à une fonction et à une branche du code épinglé avant de lui attribuer une cause.
  3. Préservez les états absent, indéfini, vide, erreur et présent séparément lorsque le code ou le rapport les expose.
  4. Vérifiez si une valeur a été comparée directement, convertie en chaîne, normalisée, modifiée ou confrontée à une liste.
  5. Énoncez le résultat limité que la branche observée étaye et laissez les causes non observées sans conclusion.

Ces étapes constituent une méthode d'interprétation utile pour une revue de confidentialité, l'analyse de régressions et l'explication d'un rapport tiers sans inventer d'identité d'appareil. Un instantané du code montre ce que celui-ci ferait avec des entrées données ; il ne fournit pas ces entrées et ne prouve pas qu'une branche non observée a été exécutée.

Questions fréquentes

L'absence d'un renderer WebGL signifie-t-elle que WebGL est désactivé ?

Non. Les champs renderer passent par l'extension facultative WEBGL_debug_renderer_info, alors que la création du contexte est vérifiée séparément. La voie peut avoir un contexte sans ajouter de valeurs renderer non masquées. Les champs absents n'identifient pas à eux seuls l'explication.

La comparaison miroir compare-t-elle toutes les valeurs WebGL ?

Non. Elle parcourt les clés de l'objet de paramètres WebGL2, exige une valeur WebGL correspondante vraie, omet trois clés nommées et compare les représentations sous forme de chaîne. Une liste de divergences vide reste limitée à ce prédicat et aux données reçues.

LowerEntropy.WEBGL signifie-t-il que le navigateur est un bot ?

Le module épinglé définit cet indicateur interne lorsqu'une de ses valeurs dérivées manque dans des listes intégrées. Le code n'en fait pas une norme WebGL universelle ; à lui seul, ce champ n'établit pas la décision d'un site à propos d'un visiteur.

Un URI de données réussi signifie-t-il que readPixels a réussi ?

Non. Le helper tente la sérialisation avant la lecture des pixels. Le catch interne de lecture peut renvoyer un URI de données avec des données pixels indéfinies. Ces champs n'ont pas le même état d'achèvement.

Sources

Conclusion pratique

Traitez le rapport comme un ensemble d'observations dépendant du code source, et non comme une étiquette d'appareil unique. Épinglez la révision d'implémentation, préservez le contexte et l'opération à l'origine de chaque valeur, et séparez les données renderer facultatives, la sérialisation d'image, la lecture des pixels et les branches de capacité dérivées. Lorsqu'un champ manque, décrivez son absence au niveau étayé par le code ; n'en déduisez ni la cause ni la décision d'un autre site.

#Creepjs#Webgl#Empreinte Du Navigateur#Capacités Graphiques#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.