Agent utilisateur : à quoi sert vraiment l’en-tête User-Agent

L'agent utilisateur est la chaîne de texte que tout client HTTP envoie dans l'en-tête User-Agent pour annoncer son logiciel, sa version et sa plateforme. Elle est purement déclarative : une option de ligne de commande suffit à la réécrire, donc elle sert à adapter un affichage ou à lire des logs, jamais à contrôler un accès.

Ce que le serveur reçoit vraiment

Chaque requête HTTP transporte une ligne qui décrit le logiciel émetteur. C'est l'agent utilisateur. La RFC 9110, section 10.1.5, publiée en juin 2022 pour remplacer la RFC 7231, en fixe la grammaire : une suite de jetons `produit/version` séparés par des espaces, chacun pouvant être suivi d'un commentaire entre parenthèses. En HTTP/2 et HTTP/3, le nom du champ s'écrit en minuscules (`user-agent`), la valeur ne bouge pas.

Voici ce qu'envoie Chrome 120 sur Windows 11 :

`Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36`

Rien là-dedans ne dit Windows 11. Le numéro interne de Windows est resté à NT 10.0, et Chrome le fige désormais à cette valeur pour tous. Si vous comptiez sur vos logs pour mesurer l'adoption d'un système d'exploitation, la mesure est fausse et le restera.

  • `Mozilla/5.0` : jeton hérité, présent chez tous les navigateurs graphiques, sans aucune valeur informative aujourd'hui
  • `(Windows NT 10.0; Win64; x64)` : commentaire de plateforme, désormais figé
  • `AppleWebKit/537.36 (KHTML, like Gecko)` : moteur de rendu, version gelée depuis Chrome 27 en 2013
  • `Chrome/120.0.0.0` : marque et version majeure, les trois derniers segments valent toujours zéro
  • `Safari/537.36` : compatibilité avec les scripts qui cherchaient Safari il y a quinze ans

Pourquoi tout le monde prétend être Mozilla

L'histoire explique le désordre. Mosaic annonçait `NCSA_Mosaic/2.0`. Netscape s'est présenté comme `Mozilla/2.0` pour recevoir les pages riches que les serveurs réservaient à Mosaic. Internet Explorer a copié Netscape en glissant `compatible; MSIE` dans le commentaire, Safari a copié les deux, Chrome a copié Safari, Edge a copié Chrome. Chaque génération a menti pour ne pas être renvoyée vers la version dégradée du site.

Le résultat tient dans un tableau.

ClientChaîne envoyéeJeton qui l'identifie
Chrome desktopMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36Chrome/
Edge... AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0Edg/
FirefoxMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0Firefox/
Safari iOSMozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1Version/ + Mobile/
Chrome AndroidMozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36Mobile Safari/
GooglebotMozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)Googlebot/
curlcurl/8.4.0curl/

Une déclaration, pas une preuve

Rien ne vérifie ce champ.

Une option suffit à le réécrire : `curl -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://exemple.fr`. Wget fait pareil avec `-U`, une extension de navigateur le fait en deux clics, et un script Python passe la valeur dans son dictionnaire `headers`. Utiliser l'agent utilisateur comme contrôle d'accès revient à laisser la porte ouverte avec un panneau qui demande de ne pas entrer.

Pour distinguer un vrai Googlebot d'un aspirateur qui usurpe sa chaîne, la méthode fiable est la résolution DNS inverse suivie d'une résolution directe. `host 66.249.66.1` doit renvoyer un nom se terminant par `.googlebot.com` ou `.google.com`, et `host` sur ce nom doit ramener exactement l'adresse de départ. Google publie aussi ses plages en JSON sur `developers.google.com/search/apis/ipranges/googlebot.json`, ce qui évite une requête DNS à chaque hit.

Client Hints : la chaîne se vide, l’information se demande

Chrome a réduit sa chaîne parce qu'elle était devenue un bon vecteur de traçage passif : envoyée à tous les tiers de la page, sans consentement, sans appel JavaScript. La réduction s'est achevée côté desktop avec Chrome 113 en 2023, le mobile a suivi. Version mineure ramenée à `0.0.0`, macOS figé à `10_15_7`, Windows à `10.0`, Android à `10`, et modèle d'appareil remplacé par la lettre `K`.

Ce qui reste utile est passé dans les Client Hints, dont le cadre est défini par la RFC 8942.

Une valeur type ressemble à `Sec-CH-UA: "Chromium";v="120", "Google Chrome";v="120", "Not?A_Brand";v="24"`. La marque factice, dont l'orthographe change d'une version à l'autre, sert de garde-fou contre les parseurs qui feraient une correspondance exacte. Firefox et Safari n'implémentent pas cette API : chez eux, `User-Agent` reste le seul signal disponible.

  • `Sec-CH-UA`, `Sec-CH-UA-Mobile`, `Sec-CH-UA-Platform` : faible entropie, envoyés d'office par les navigateurs Chromium
  • `Sec-CH-UA-Full-Version-List`, `Sec-CH-UA-Arch`, `Sec-CH-UA-Model`, `Sec-CH-UA-Platform-Version` : forte entropie, il faut les réclamer
  • `Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Model` dans la réponse : le navigateur les joindra aux requêtes suivantes vers la même origine
  • `navigator.userAgentData.getHighEntropyValues(["model"])` côté JavaScript, sous forme de promesse, uniquement sur Chromium

Les pièges qui cassent des sites en production

Le premier s'appelle `Vary: User-Agent`. Google le recommande pour le dynamic serving, et sur un CDN il fabrique une entrée de cache par variante de chaîne rencontrée. Comme ces chaînes sont presque uniques dès qu'on sort de Chrome récent, le taux de hit s'effondre et l'origine encaisse le trafic qu'elle croyait déléguer. Si vous devez servir deux rendus, séparez les URL ou basculez côté client.

Le deuxième, c'est la détection par expression régulière.

Un test sur `/Chrome/` attrape Edge, Opera, Brave, Vivaldi et Samsung Internet, qui portent tous ce jeton. Un test sur `/Safari/` attrape Chrome. Et depuis iPadOS 13, Safari sur iPad annonce `Macintosh; Intel Mac OS X`, ce qui fait basculer les iPads du côté desktop dans tous les scripts écrits avant 2019. Cherchez le jeton le plus spécifique d'abord, `Edg/` avant `Chrome/`, ou testez la fonctionnalité plutôt que le navigateur.

Troisième piège : le blocage des agents vides ou inconnus. Beaucoup de pare-feu applicatifs renvoient un 403 quand `User-Agent` est absent, ce qui casse une sonde de supervision en curl, un webhook ou un client interne qui n'a jamais pris la peine de se nommer. Dans l'autre sens, Apache limite chaque ligne d'en-tête à 8190 octets par défaut via `LimitRequestFieldSize` : une chaîne gonflée par une extension ou un antivirus peut franchir ce seuil et provoquer un 400 que personne ne relie à l'agent utilisateur.

Dans les journaux, le champ s'appelle `$http_user_agent` sous nginx et `%{User-Agent}i` sous Apache, en dernière position du format combined.

Trois choses qu’on confond avec l’agent utilisateur

Le terme désigne d'abord un logiciel, pas une chaîne. Dans la RFC 9110, un user agent est n'importe quel client qui émet une requête : navigateur, robot d'indexation, lecteur de flux, application mobile. La chaîne n'est que sa carte de visite.

Côté navigateur, `navigator.userAgent` renvoie exactement la même valeur que l'en-tête, alors que `navigator.userAgentData` renvoie un objet structuré et n'existe que sur Chromium.

  • En SIP (RFC 3261), user agent désigne un terminal téléphonique, découpé en UAC côté appelant et UAS côté appelé. Le protocole a son propre en-tête `User-Agent`, sans rapport avec HTTP.
  • Dans `robots.txt` (RFC 9309), la directive `User-agent:` ne compare pas la chaîne complète mais un jeton produit, insensible à la casse : `User-agent: Googlebot` s'applique à toute chaîne contenant ce jeton.
  • En messagerie, MUA signifie Mail User Agent, c'est-à-dire le client de courrier, à ne pas confondre avec le MTA qui achemine les messages.

Questions fréquentes

Comment voir mon agent utilisateur ?

Dans la console du navigateur, tapez `navigator.userAgent`. Pour vérifier ce qu'un outil en ligne de commande envoie réellement, `curl -v https://votresite.fr 2>&1 | grep -i user-agent` affiche la ligne transmise. L'onglet Réseau des outils de développement montre la même valeur dans les en-têtes de requête.

Changer d’agent utilisateur protège-t-il ma vie privée ?

Pas vraiment, et cela peut faire l'inverse. Une chaîne rare vous rend plus identifiable qu'une chaîne banale, puisque l'empreinte se construit sur la combinaison de signaux. Se fondre dans le Chrome le plus courant protège mieux que se déclarer Netscape 4 sur OS/2.

Puis-je bloquer un robot en filtrant son User-Agent ?

Contre un robot poli, oui : `robots.txt` et un filtre sur le jeton suffisent. Contre un aspirateur, non, puisqu'il changera de chaîne en une ligne de configuration. Le blocage sérieux se fait sur l'adresse IP, l'ASN, la limitation de débit ou un défi côté client.

L’en-tête User-Agent est-il obligatoire ?

Non. La RFC 9110 indique qu'un client devrait l'envoyer, sans en faire une obligation, et elle recommande même de rester bref pour limiter l'exposition. En pratique, beaucoup de serveurs et de pare-feu applicatifs rejettent les requêtes sans agent utilisateur, il vaut donc mieux en déclarer un explicite pour vos scripts.

Servir un contenu différent à Googlebot, est-ce du cloaking ?

Oui si la différence porte sur le contenu et pas seulement sur la mise en forme. Googlebot rend les pages avec un moteur proche d'un Chrome récent, et l'outil d'inspection d'URL de la Search Console montre le rendu obtenu. Comparez ce rendu à celui d'un visiteur avant de conclure.

Testez vos connaissances

Quiz rapide Question 1 sur 3

Que signifie `Mozilla/5.0` au début de presque toutes les chaînes ?

À lire aussi

bot · codes statut http · cache · confidentialite en ligne

Newsletter

Recevez nos guides IP & réseau

Nouveaux outils, définitions et astuces sécurité, directement par email. Pas de spam, désinscription en un clic.