Détection du mode sans tête dans CreepJS : trois verdicts
Une sonde sur CreepJS : les signaux mous, les bits durs et les contrôles d’emballage sont notés séparément, donc une page nettoyée rapporte encore un pourcentage.
BotBrowser Team
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 permet de rejouer un fixture de même origine autorisé sous un profil déclaré et de garder une trace bornée de ce qu’une page a rapporté sur son propre environnement, mais il ne peut pas rendre une surface mince épaisse, ne peut pas transformer une surface restaurée en un signal qui n’a jamais été contrôlé, ni changer la façon dont une bibliothèque regroupe ses propres constats. Cette revue lit CreepJS depuis son code public, reproduit les trois groupes de verdict qu’il calcule et consigne ce que vaut un seul signal dans chaque groupe, combien de signaux mous une page doit réunir pour que le groupe mou se lise comme sans tête, quels bits durs survivent à une page qui a nettoyé les évidents, et pourquoi un pourcentage d’un groupe n’est pas comparable à celui d’un autre.
Résumé
- CreepJS rapporte le mode sans tête en trois pourcentages séparés, pas un :
likeHeadlesssur 16 signaux mous,headlesssur 3 bits durs, et un groupe d’emballage sur 5 contrôles. - Un bureau avec tête et gestionnaire de fenêtres réel obtient
likeHeadless=0% headless=0% wrapper=0%. - Le profil sans tête classique atteint
likeHeadless=44% (7/16)alors que son groupe dur reste à0%, parce que les signaux mous et les bits durs mesurent des choses différentes. - Un pilote qui laisse fuir son drapeau et son jeton obtient
headless=100% (3/3), le seul groupe au maximum dans cette exécution. - Un seul signal vaut 6% dans le groupe mou, 33% dans le dur et 20% dans celui d’emballage, donc le même constat pèse très différemment selon le groupe.
- Une page qui restaure l’objet chrome, les plugins, les types MIME, les données d’agent utilisateur et le lecteur PDF rapporte encore
likeHeadless=13% (2/16), parce que la géométrie d’écran n’a pas été touchée. - Fixer une taille de fenêtre plausible le fait tomber à
likeHeadless=6% (1/16), avec un moteur de rendu logiciel comme dernier signal mou. - Un emballage qui place mal l’objet chrome, casse son runtime et modifie
Function.prototype.toStringobtientwrapper=60% (3/5)tandis que les deux autres groupes restent à zéro. - Le signal
noTaskbarest une simple égalité de géométrie, donc une fenêtre maximisée sur un vrai bureau le déclenche aussi.
Sommaire
- Pourquoi les trois groupes sont séparés
- Ce que vaut un signal dans chaque groupe
- Quels signaux survivent à une page nettoyée
- Où les signaux mous exagèrent un cas
- Consigner une lecture sans tête
Pourquoi les trois groupes sont séparés
La détection du mode sans tête est souvent décrite comme une question à une réponse, et CreepJS rapporte délibérément trois réponses. Les groupes viennent du même module et mesurent des types de preuve différents :
headed-desktop -> likeHeadless=0% (0/16) headless=0% (0/3) wrapper=0% (0/5)
Le premier groupe contient seize signaux mous : pas d’objet chrome, pas de plugins, pas de types MIME, une plateforme de client hints vide, un lecteur PDF désactivé, un écran sans barre des tâches, une fenêtre d’affichage égale à l’écran, un moteur de rendu logiciel et quelques lacunes de capacités. Chacun est une surface qui paraît mince, et chacun est aussi une surface qu’un déploiement légitime peut avoir.
Le drapeau du pilote dans ce groupe est la même valeur qu’un détecteur de mensonges lit quand il vérifie si un natif se rapporte encore, et fonctions natives remplacées et ce que voit une liste de toString le consigne. Le deuxième groupe contient trois bits durs, et ils sont durs dans un autre sens : le drapeau du pilote, un jeton HeadlessChrome dans l’agent utilisateur, et le même jeton dans un Worker. Ils ne décrivent pas une surface mince ; ils décrivent un navigateur qui s’est annoncé.
Une chaîne de décision bâtie sur plusieurs groupes est notée et filtrée autrement que ces trois pourcentages, et pourquoi un seul signal bizarre ne condamne pas le consigne. Le troisième groupe contient cinq contrôles d’emballage : si un proxy d’iframe est détectable, si l’objet chrome occupe une position invraisemblable dans l’ordre des clés de window, si chrome.runtime se comporte comme un vrai objet, si Function.prototype.toString a été modifié, et si les GPU du fil principal et du Worker divergent. Ils décrivent une page qui a édité son propre environnement, pas une page qui paraît simplement mince.
Trois groupes, trois types d’affirmation. Les fondre en un seul nombre perdrait la distinction entre « cet environnement est minimal », « ce navigateur a dit qu’il était automatisé » et « cette page s’est éditée elle-même », et ces trois cas appellent des réponses entièrement différentes.
Ce que vaut un signal dans chaque groupe
Les pourcentages ne sont pas comparables entre groupes, parce que chacun est une part d’un dénominateur différent. La sonde énonce le poids d’un seul constat dans chacun :
weight:likeHeadless -> one signal = 6%
weight:headless -> one signal = 33%
weight:wrapper -> one signal = 20%
Un signal mou déplace le groupe mou de six points, tandis qu’un bit dur déplace le groupe dur de trente-trois. Un rapport qui imprime « 44% » et « 33% » côte à côte invite à les traiter comme la même échelle, et ce n’est pas le cas : 44% du groupe mou représente sept surfaces minces, et 33% du groupe dur représente un navigateur qui s’est annoncé.
Le groupe mou exige en outre beaucoup de signaux avant de se lire comme majoritairement sans tête :
likeHeadless:1-of-16 -> 6%
likeHeadless:4-of-16 -> 25%
likeHeadless:8-of-16 -> 50%
likeHeadless:12-of-16 -> 75%
likeHeadless:16-of-16 -> 100%
La moitié du groupe demande huit surfaces minces à la fois. C’est une barre difficile à franchir par accident, et c’est pourquoi le pourcentage mou décrit à quel point un environnement est minimal plutôt que la probabilité qu’il soit sans tête.
La ligne de comparaison dit la même chose depuis l’autre côté :
compare -> all-16-soft=100% vs one-hard=33% (groups are reported separately)
Une page avec les seize signaux mous se lit à 100% dans son groupe, et une page avec un bit dur se lit à 33% dans le sien. Aucun n’est plus grand dans un sens significatif, parce qu’ils répondent à des questions différentes. Qui trie les deux pourcentages trie deux unités différentes.
Quels signaux survivent à une page nettoyée
Ce qui est intéressant, c’est ce qui se passe quand une page range les signaux évidents. La sonde fournit un état où l’objet chrome, les plugins, les types MIME, la plateforme de client hints et le lecteur PDF ont été restaurés, et seule la géométrie d’écran est restée telle quelle :
cleaned-obvious-tells -> likeHeadless=13% (2/16) headless=0% (0/3) wrapper=0% (0/5)
cleaned-plus-window -> likeHeadless=6% (1/16) headless=0% (0/3) wrapper=0% (0/5)
Restaurer cinq surfaces laisse encore treize pour cent, parce que les deux signaux de géométrie n’ont jamais été touchés. Fixer une taille de fenêtre plausible l’amène à six, avec un moteur de rendu logiciel comme dernier signal mou. Les groupes dur et d’emballage restent à zéro tout du long, ce qui est la partie utile : nettoyer des surfaces ne crée pas de constats d’emballage, cela ne fait que retirer les mous.
Cette asymétrie compte pour qui lit un rapport après un changement. Une page passée de quarante-quatre à six pour cent n’est devenue ni plus ni moins sans tête ; elle est devenue moins minimale. Le groupe dur, celui qui décrit un navigateur qui s’annonce, n’a pas bougé du tout, et qui ne regarde que le total croira qu’une amélioration a eu lieu alors que l’affirmation de fond n’a pas changé.
L’inverse vaut aussi. Le groupe d’emballage peut monter sans aucun signal mou :
wrapper-wrapped -> likeHeadless=0% (0/16) headless=0% (0/3) wrapper=60% (3/5)
Une page qui garde chaque surface épaisse mais place mal l’objet chrome, casse son runtime et modifie Function.prototype.toString obtient soixante pour cent dans le groupe d’emballage alors que les deux autres restent vides. C’est un constat entièrement différent d’un environnement mince, et il n’est visible que parce que les groupes sont séparés.
Où les signaux mous exagèrent un cas
Plusieurs signaux mous sont des conditions ordinaires qu’un déploiement légitime produit aussi, et la sonde en fixe deux.
Le signal de permissions exige que deux conditions indépendantes concordent avant de se déclencher :
permissions-bug -> prompt+denied=true prompt+default=false granted+denied=false
Il ne se déclenche que lorsqu’une requête de permissions rapporte prompt alors que la permission de notification est denied. Aucune des deux conditions seule ne le déclenche, ce qui est un resserrement délibéré : un navigateur qui refuse simplement les notifications par politique n’est pas signalé, et seul le couple incohérent l’est.
Le signal de la barre des tâches est le cas opposé, et c’est le plus faible du groupe :
no-taskbar -> 1080/1080+1920/1920=true 1080/1040+1920/1920=false
C’est une simple égalité entre l’écran et sa zone disponible, donc toute fenêtre maximisée sur un vrai bureau avec la barre masquée le déclenche, tout comme un kiosque ou un appareil plein écran. Un seul point du groupe mou ne vaut pas grand-chose isolément, et celui-ci vaut moins que ses six pour cent ne le suggèrent.
La leçon pour un déploiement porte sur les surfaces où investir. Restaurer plugins et types MIME déplace le groupe mou, mais la géométrie et le nom du moteur de rendu sont ceux qui restent après avoir rangé tout le reste. Un profil qui réussit les surfaces faciles et laisse la géométrie intacte se lit comme six pour cent mou, et qui ignore la taille des groupes le lira comme « presque rien » alors qu’il s’agit d’un signal précis.
Consigner une lecture sans tête
Une lecture sans tête étaye une affirmation bornée : cette version de la bibliothèque, ces états de signal ont produit ces trois pourcentages. Quatre champs la gardent vérifiable :
- Le commit de la bibliothèque et les trois listes de signaux, parce qu’une liste qui gagne ou perd une clé change chaque pourcentage sans aucun changement sur la page.
- Les noms des signaux déclenchés par groupe, parce que six et trente-trois pour cent décrivent des types de preuve différents et que le nombre seul cache lequel.
- Les dénominateurs de chaque groupe, parce que qui compare un pourcentage mou à un pourcentage dur compare deux unités différentes.
- Les signaux qui n’ont pas été évalués, parce que plusieurs exigent une page vivante et qu’une reproduction statique les fournit en entrée.
Sources publiques
- CreepJS
- Module de détection sans tête de CreepJS
- MDN : Navigator.webdriver
- MDN : Navigator.plugins
- MDN : Permissions API
- BotBrowser : référence de cohérence d’automatisation
Conclusion pratique
Lisez les trois pourcentages comme trois constats séparés plutôt qu’un seul score, parce que le pourcentage mou décrit à quel point un environnement est minimal, le dur décrit un navigateur qui s’est annoncé, et celui d’emballage décrit une page qui s’est éditée elle-même. Traitez une chute de quarante-quatre à six pour cent comme un changement de la quantité d’environnement exposée, non comme un changement du caractère sans tête, puisque le groupe dur n’a pas bougé. Quand un rapport montre un groupe qui monte tandis que les autres restent vides, cherchez les contrôles d’emballage plutôt que des surfaces manquantes. Pour la façon dont une bibliothèque réduit les résultats de groupe à une décision ordonnée, lisez les groupes de signaux de CreepJS et leur combinaison ; pour ce qu’un seul contrôle de texte source peut voir, lisez fonctions natives remplacées et ce que voit une liste de toString.
Cet article fait partie du guide : Qu'est-ce qu'une empreinte de navigateur ?
Articles Connexes
Les groupes de signaux de CreepJS et leur combinaison
EmpreinteLire les signaux d’empreinte du navigateur
EmpreintePourquoi un seul signal bizarre ne condamne pas
EmpreinteBotD : quels détecteurs s’exécutent vraiment
EmpreinteCe que les suites de détection publiques testent vraiment
EmpreinteSource aléatoire de crypto-js : quelle branche
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.