Retour au Blog
Empreinte

Client Hints Fingerprinting : en-têtes HTTP et identité

Les en-têtes Client Hints comme sec-ch-ua décrivent marque, version et plateforme à chaque requête. Voyez d'où viennent les écarts et comment les comparer avec JavaScript.

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.

Chaque requête envoyée par un navigateur basé sur Chromium peut porter une description courte et structurée du navigateur qui l'envoie. Ces descriptions s'appellent les Client Hints, et trois d'entre elles sont envoyées par défaut : Sec-CH-UA, Sec-CH-UA-Mobile et Sec-CH-UA-Platform. Elles arrivent sous forme d'en-têtes de requête avant l'exécution du moindre script de la page, de sorte qu'un serveur peut lire la marque du navigateur, la version majeure, la catégorie d'appareil et la famille de système d'exploitation dès la première navigation.

Les Client Hints ont été introduits pour remplacer la longue chaîne User-Agent au format libre par quelque chose de plus étroit et de plus facile à contrôler. En pratique, ils ont aussi créé un deuxième endroit où le navigateur se décrit lui-même. Lorsque les en-têtes disent une chose, que navigator.userAgentData en dit une autre et que la chaîne User-Agent en dit une troisième, ce désaccord est en soi un signal qu'une revue d'empreinte remarquera. Les sections ci-dessous couvrent ce que chaque couche indique, d'où viennent les désaccords, comment comparer les couches pour une session et ce que BotBrowser documente, ou ne documente pas, sur ce sujet.

Comparaison des Client Hints pour une session. Les en-têtes HTTP, navigator.userAgentData et les contextes de worker sont comparés à une seule identité configurée.

Ce que le navigateur envoie avant l'exécution de tout script

Les Client Hints se répartissent en deux groupes. Les hints à faible entropie sont envoyés par défaut. Sec-CH-UA énumère les marques du navigateur avec leurs versions majeures, Sec-CH-UA-Mobile indique si le navigateur demande l'expérience mobile et Sec-CH-UA-Platform nomme la famille du système d'exploitation. Comme ces trois valeurs décrivent de façon similaire une grande part des navigateurs, la spécification les juge à faible risque et autorise le navigateur à les envoyer sans qu'on les lui demande.

Les hints à forte entropie sont les plus détaillés : la liste complète des versions, la version de la plateforme, l'architecture du processeur, le nombre de bits, le modèle de l'appareil et l'information indiquant si un navigateur 32 bits tourne sur un système 64 bits. Un serveur ne les reçoit qu'après avoir donné son accord par un en-tête de réponse Accept-CH qui nomme les hints souhaités, et le navigateur les inclut alors dans les requêtes suivantes vers cette origine. Un serveur qui a besoin d'un hint dès la première requête peut aussi utiliser Critical-CH, qui demande au navigateur de relancer la requête avec le hint joint. Les cadres tiers ne reçoivent un hint que si la page qui les intègre le délègue avec un en-tête Permissions-Policy.

JavaScript dispose de sa propre voie vers les mêmes données. navigator.userAgentData expose immédiatement les marques, l'indicateur mobile et la plateforme, et getHighEntropyValues() renvoie les valeurs détaillées sous forme de promesse lorsqu'une page demande des noms précis. Les deux voies sont censées décrire un seul navigateur, c'est pourquoi leur comparaison est le contrôle de cohérence le plus direct.

Une requête par défaut d'un navigateur de bureau de la famille Chrome porte des en-têtes ayant la forme des lignes ci-dessous. L'entrée GREASE exacte et sa position changent d'une version de Chrome à l'autre ; les valeurs montrent donc la forme des données et ne sont pas à recopier.

Sec-CH-UA: "Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "Windows"

L'en-tête User-Agent existe toujours. Chrome a réduit le niveau de détail qu'il contient, ce qui a déplacé les informations précises de version et de plateforme vers les Client Hints. Un serveur détient donc deux descriptions d'un même navigateur et peut vérifier si elles concordent. Pour une comparaison plus détaillée entre la chaîne et les hints structurés, consultez Custom User Agent.

La liste des marques contient aussi une entrée GREASE, une marque volontairement étrange comme Not.A/Brand dont le texte, la version et la position changent avec le temps. Son but est d'empêcher les serveurs de figer une liste dans leur code. Pour qui configure une identité de navigateur, GREASE rappelle que la liste des marques suit une règle dépendant de la version, et qu'une liste écrite à la main peut sembler fausse même si chaque nom de marque est réel.

D'où viennent les incohérences

Une identité de navigateur comporte plusieurs surfaces, et chacune est lue par une partie différente de la page ou du serveur. Une incohérence apparaît lorsque deux surfaces décrivent des navigateurs différents. Les sources les plus courantes sont les suivantes :

  • Une chaîne User-Agent qui nomme une version du navigateur alors que Sec-CH-UA indique une autre version majeure.
  • Une plateforme dans Sec-CH-UA-Platform qui diffère de celle de navigator.userAgentData, ou un indicateur mobile qui contredit la plateforme.
  • Une liste de marques dans les en-têtes qui diffère de celle renvoyée par JavaScript, par exemple Edge d'un côté et Chrome seul de l'autre.
  • Un worker qui indique une identité différente de celle du thread principal parce qu'un remplacement n'a été appliqué qu'aux pages.
  • Des remplacements appliqués par deux outils différents, par exemple un profil plus une modification de User-Agent au niveau du framework ou de CDP, où chaque outil couvre un sous-ensemble différent de surfaces.
  • Une configuration qui était correcte au moment de son écriture mais qui retarde désormais sur la version de Chrome ayant produit le binaire du navigateur.

Les éléments côté en-têtes peuvent être lus sur le serveur sans exécuter de script de page : les en-têtes par défaut arrivent avec la première requête, et un serveur qui demande des hints à forte entropie les reçoit au cycle de requête suivant et peut les comparer avec le User-Agent. Les comparaisons de navigator.userAgentData et des workers, elles, nécessitent un script. Du point de vue de la vie privée, les Client Hints s'ajoutent à l'ensemble des valeurs qui, combinées à d'autres signaux, permettent de distinguer un navigateur. Cover Your Tracks, de l'EFF, montre comment des combinaisons de valeurs ordinaires deviennent distinctives, et les Client Hints sont un ingrédient de plus dans cette combinaison. Un ensemble cohérent de valeurs est aussi plus facile à revoir qu'un assemblage hétéroclite, parce que chaque différence observée est une vraie question et non du bruit.

Prenons une équipe qui charge un profil décrivant un poste Windows puis, via un framework de test, fixe une chaîne User-Agent d'un autre système d'exploitation. Le framework couvre la chaîne et peut-être quelques métadonnées, le profil couvre ses propres surfaces, et aucun des deux outils ne connaît l'autre. Le résultat est une session où les en-têtes et les valeurs visibles par les scripts décrivent deux machines différentes. La solution n'est pas un meilleur remplacement. La solution consiste à choisir une source pour chaque valeur et à supprimer l'autre.

Les contextes d'exécution comptent autant que les types de requêtes. Un worker dédié, un worker partagé et un service worker ont chacun leur propre portée globale, et l'interface NavigatorUAData est exposée dans les portées de worker comme dans les fenêtres. Une page peut donc lire les valeurs de marque et de plateforme à l'intérieur d'un worker et les comparer aux siennes. Un remplacement qui ne modifie que la page laisse cette comparaison ouverte.

Les valeurs liées à la plateforme méritent une attention particulière, car elles dépendent les unes des autres. Le nom de la plateforme, sa version, l'architecture, le nombre de bits et l'indicateur mobile décrivent un seul appareil. Une version de plateforme normale pour un système d'exploitation paraît fausse à côté du nom d'un autre, et un indicateur mobile à vrai à côté d'une architecture de bureau soulève aussitôt une question. Lorsque vous modifiez l'une de ces valeurs, revoyez-les toutes ensemble.

Comparer en-têtes et valeurs JavaScript pour une session

L'objectif de la comparaison est étroit : confirmer qu'une session indique une seule identité partout où vous pouvez la lire. Il n'est pas nécessaire d'utiliser une page de notation tierce pour cela. Une page et un serveur que vous maîtrisez suffisent, et ils vous permettent de demander des hints à forte entropie volontairement.

  1. Servez une page de test en HTTPS depuis un serveur que vous maîtrisez et enregistrez les en-têtes de requête qu'il reçoit lors de la première navigation.
  2. Ajoutez un en-tête de réponse Accept-CH listant les hints à forte entropie que vous voulez comparer, tels que Sec-CH-UA-Full-Version-List, Sec-CH-UA-Platform-Version et Sec-CH-UA-Arch, puis chargez la page une seconde fois pour que le navigateur les inclue.
  3. Dans la page, lisez navigator.userAgentData et appelez getHighEntropyValues() avec les mêmes noms, puis notez les résultats à côté des en-têtes.
  4. Répétez les lectures JavaScript depuis un worker dédié et, si votre site en utilise un, depuis un service worker, et notez toute différence avec le thread principal.
  5. Comparez les noms de marque, les versions majeures, la plateforme, la version de la plateforme, l'architecture, le nombre de bits, le modèle et l'indicateur mobile, ajoutez la chaîne User-Agent, et notez chaque différence avec la requête ou le contexte qui l'a produite.

Des pages publiques peuvent compléter cette démarche. Cover Your Tracks, de l'EFF, montre comment votre navigateur apparaît à un traceur typique, ce qui donne un second avis sur le caractère distinctif de l'ensemble. Ces pages conviennent moins à une comparaison en-tête par en-tête, car elles ne disent pas quelle requête a produit quelle valeur. Gardez votre propre page de test pour cela et considérez les outils publics comme du contexte. Consultez Verify Browser Fingerprint pour une routine de vérification plus large.

Notez les résultats dans une grille simple avec une ligne par valeur et une colonne par surface : en-tête de requête, thread principal, worker et chaîne User-Agent. Une ligne où les colonnes diffèrent est un constat. Une ligne où elles concordent est une preuve pour cette seule valeur, et elle ne dit rien sur la façon dont un site web donné traitera la session.

Lorsque vous trouvez une différence, remontez depuis la surface fautive. Demandez-vous quel outil ou quelle option est responsable de cette surface, vérifiez si un second outil y écrit aussi, et supprimez la source en double. Relancez ensuite toute la comparaison, pas seulement la ligne en échec, car la modification d'une valeur peut révéler une incohérence chez sa voisine.

Une seule source de Client Hints avec BotBrowser

BotBrowser documente que la configuration des options d'identité, dont --bot-browser-brand et les options de User-Agent et de plateforme, génère des Client Hints cohérents : marques, jetons GREASE, valeurs à forte entropie et en-têtes HTTP de Client Hints alignés sur navigator.userAgentData dans le thread principal, les Workers et les requêtes HTTP. Pour la comparaison décrite plus haut, cela signifie que vous pouvez confronter les en-têtes et les valeurs JavaScript d'une session à une seule identité configurée, au lieu de réconcilier plusieurs sources à la main. BotBrowser ne peut pas contrôler la façon dont un site web classe les Client Hints ou d'autres signaux d'empreinte, ne peut pas garantir un résultat de détection ou d'accès, et ne peut pas réconcilier les modifications de User-Agent au niveau de CDP ou d'un framework appliquées en dehors de BotBrowser. Le User-Agent personnalisé et le contrôle complet de userAgentData nécessitent la licence ENT Tier3 documentée.

La voie documentée est courte. Chargez un profil et ajoutez des options d'identité seulement lorsque vous avez besoin d'une marque ou d'une plateforme différente de celle du profil. Les options se placent dans les arguments de lancement, pas dans une option du framework. À partir de ces entrées, BotBrowser génère les valeurs dépendantes ; vous n'écrivez donc ni liste de marques ni entrée GREASE vous-même.

chromium-browser \
  --bot-profile="path/to/profile.enc" \
  --bot-browser-brand=edge \
  --bot-ua-full-version=142.0.7444.60 \
  --bot-brand-full-version=142.0.3595.65

Les valeurs de marque documentées sont chrome, edge, brave, opera, chromium et webview. Chaque marque suit son propre rythme de versions, de sorte que les versions complètes d'Edge et d'Opera diffèrent de la version de Chromium même lorsque la version majeure est commune. Utilisez --bot-ua-full-version pour la version de Chromium et --bot-brand-full-version pour la version propre à la marque, et gardez les deux sur la même version majeure. Le changement de marque est documenté avec la licence ENT Tier2, tandis que la marque WebView et le User-Agent personnalisé sont documentés avec ENT Tier3.

Considérez le profil et les options d'identité comme la source unique. Si vous définissez aussi un User-Agent via CDP ou une option de framework, ce remplacement est appliqué en dehors de BotBrowser, et BotBrowser ne le réconcilie pas avec les Client Hints générés. Choisissez une source pour chaque valeur. Lorsque vous passez --user-agent, utilisez les marqueurs documentés comme {ua-full-version} afin que la chaîne suive les mêmes options que les hints.

Après chaque version de Chrome, vérifiez que --bot-ua-full-version conserve la même version majeure de Chromium que votre binaire BotBrowser. Lorsque le binaire passe à une nouvelle version majeure, utilisez un profil et des options qui ciblent cette version. Le symptôme documenté d'une incohérence est un ensemble de Client Hints qui ne concorde pas avec le binaire, et une version périmée est une incohérence entre la configuration et le navigateur qui l'exécute.

Questions courantes sur les Client Hints

Les Client Hints sont-ils envoyés lorsque JavaScript est désactivé ?

Les hints à faible entropie par défaut sont des en-têtes de requête, ils ne dépendent donc pas du script de la page. Les hints à forte entropie dépendent de l'accord du serveur via Accept-CH. L'interface JavaScript, naturellement, a besoin qu'un script s'exécute. Cette séparation explique pourquoi une revue des en-têtes et une revue du script répondent à des questions différentes, et pourquoi les deux font partie d'un contrôle de cohérence.

Un serveur peut-il recevoir un hint à forte entropie qu'il n'a jamais demandé ?

Pas par les en-têtes de requête. Le navigateur ne les joint qu'après un accord préalable. Un script exécuté dans la page peut en revanche appeler getHighEntropyValues() et transmettre le résultat de lui-même, ce qui constitue une autre voie avec ses propres contrôles. Lorsque vous examinez le comportement d'un site, regardez les deux voies.

Un framework de test peut-il définir les Client Hints ?

Les frameworks de test et le protocole DevTools peuvent remplacer la chaîne User-Agent et, dans certains cas, des métadonnées associées. Ce qu'un remplacement couvre dépend de l'outil, et les remplacements issus d'outils différents peuvent se contredire. Vérifiez chaque surface avec la comparaison ci-dessus. BotBrowser ne réconcilie pas les remplacements appliqués en dehors de BotBrowser ; gardez donc les valeurs d'identité en un seul endroit.

Quelle est la différence entre Sec-CH-UA et Sec-CH-UA-Full-Version-List ?

Sec-CH-UA porte les marques avec leurs versions majeures et est envoyé par défaut. Sec-CH-UA-Full-Version-List porte la chaîne de version complète de chaque marque et constitue un hint à forte entropie qui exige un accord préalable. En JavaScript, la même séparation apparaît : brands pour les versions majeures et fullVersionList pour les versions détaillées. Les deux doivent nommer les mêmes marques et les mêmes versions majeures.

Des Client Hints concordants décident-ils du traitement d'une session par un site ?

Non. Les Client Hints sont un signal d'empreinte parmi beaucoup d'autres. La cohérence supprime un type d'incohérence, mais les sites web combinent de nombreuses autres entrées, et BotBrowser ne peut pas garantir une classification, un résultat de suivi ou un résultat d'accès. Considérez une comparaison propre comme un contrôle de qualité de votre propre configuration, et rien de plus.

Quelles options de BotBrowser influencent les Client Hints ?

Les options d'identité documentées sont --user-agent, --bot-platform, --bot-platform-version, --bot-model, --bot-architecture, --bot-bitness et --bot-mobile, ainsi que les options complémentaires --bot-browser-brand, --bot-ua-full-version et --bot-brand-full-version. L'option --user-agent accepte des marqueurs qui lisent les autres options, de sorte que la chaîne et les hints reposent sur les mêmes valeurs.

Liste de contrôle avant de vous fier à une configuration

Une courte liste rend la revue reproductible. Appliquez-la chaque fois que vous modifiez un profil, une marque, une option de plateforme ou le binaire du navigateur.

  • Chaque valeur a une seule source : le profil, une option d'identité ou rien d'autre.
  • Les marques, la plateforme et l'indicateur mobile concordent entre les en-têtes de requête, le thread principal et les workers.
  • Les valeurs à forte entropie demandées via Accept-CH correspondent aux résultats de getHighEntropyValues().
  • La chaîne User-Agent et les Client Hints nomment la même version majeure de Chromium.
  • La version majeure de --bot-ua-full-version correspond au binaire BotBrowser après chaque version.
  • Le niveau de licence couvre les options utilisées.

Pour aller plus loin, Navigator Properties Fingerprinting traite des valeurs de navigator visibles par les scripts qui accompagnent navigator.userAgentData, et What Is Browser Fingerprinting donne le contexte plus large sur la façon dont les signaux se combinent.

Sources publiques

#client hints#Sec-Ch-Ua#fingerprinting#GREASE#user agent#confidentialité#identité du navigateur#en-têtes HTTP

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.