Qu'est-ce que le fingerprinting TLS JA4, et que révèle-t-il vraiment ?
Une empreinte JA4 décrit la façon dont un client parle TLS, avant même d'envoyer le moindre en-tête. Voici sa construction, pourquoi elle a remplacé JA3, ce qu'elle attrape et où elle cesse d'être une preuve.
La première chose qu'envoie un client n'est pas un en-tête. C'est un client hello TLS : la liste des suites de chiffrement qu'il prend en charge, les extensions qu'il souhaite, les versions de protocole qu'il accepte et le protocole applicatif qu'il espère parler. Tout cela arrive en clair, avant la moindre ligne de requête, avant le moindre User-Agent. Une empreinte JA4 est un résumé compact de ce message, et elle est intéressante pour une raison : le client ne l'a pas choisie comme une affirmation sur lui-même. Elle découle de la bibliothèque TLS sur laquelle il a été construit.
C'est donc un signal d'une autre nature que tout ce qui se trouve dans la couche HTTP. Un User-Agent est une phrase que le client rédige. Une empreinte JA4 tient plutôt de l'accent.
Lire la chaîne
Une valeur JA4 comporte trois parties séparées par des tirets bas :
t13d1516h2_8daaf6152771_b186095e22b6
La première partie se lit sans consultation. t signifie TCP, un q à cette place signifierait
QUIC. 13 correspond à TLS 1.3. d indique qu'un SNI était présent, donc que le client demandait
un domaine plutôt que de se connecter à une IP nue. 15 est le nombre de suites de chiffrement
proposées et 16 celui des extensions. h2 est la valeur ALPN : ce client demandait HTTP/2.
La deuxième partie est un hachage tronqué de la liste des suites de chiffrement, triée. La troisième couvre la liste des extensions et les algorithmes de signature, triés eux aussi. Les valeurs GREASE, ces entrées volontairement inutiles que les navigateurs insèrent pour garder les middleboxes honnêtes, sont retirées avant le hachage.
Le tri a l'air d'un détail. C'est toute la raison d'être du format.
Pourquoi JA3 a cessé de fonctionner
JA3, son prédécesseur de 2017, hachait les mêmes champs dans leur ordre sur le fil. Cela fonctionnait tant que les piles TLS restaient prévisibles. Puis Chrome a livré la permutation des extensions début 2023, mélangeant l'ordre des extensions de son client hello à chaque connexion, et une seule installation de Chrome s'est mise à produire un hachage JA3 différent par requête. Les règles bâties sur des allowlists JA3 sont passées de précises à inutiles en un cycle de version.
JA4 trie avant de hacher, un réordonnancement ne change donc rien. Il garde aussi le préfixe lisible en dehors du hachage, ce qui permet de distinguer une connexion QUIC d'une connexion TCP, ou de repérer un client qui ne propose que trois suites de chiffrement, sans base de valeurs connues. Le reste de la famille JA4+ couvre d'autres couches : JA4H pour les en-têtes HTTP, JA4T pour les options TCP, JA4S pour la réponse du serveur. L'essentiel du travail de détection passe par la variante TLS.
Voir ce que révèle l'origine de la connexion
Ce qu'elle attrape
La version honnête : JA4 est très efficace pour attraper les clients qui n'ont jamais cherché à se fondre dans la masse.
Un script Python qui utilise requests produit un client hello qu'aucun navigateur ne produit. Le
transport par défaut de Go dans net/http a sa propre forme reconnaissable. curl aussi, une
vieille version d'OpenSSL aussi, et le client HTTP intégré à la plupart des SDK également. Aucun
ne se cache, ils sont simplement ce qu'ils sont, et l'empreinte le dit même quand la requête se
présente comme Chrome 141 sur macOS.
C'est cet écart qui est utile. Prise seule, une empreinte de client HTTP Go n'indique rien de mauvais. Associée à un User-Agent qui revendique un navigateur, elle vous dit que le client se décrit de façon inexacte, et les raisons de le faire sont rarement innocentes.
La même logique vaut pour les navigateurs headless, mais plus faiblement. Un vrai build de Chrome
et un Chrome piloté par Playwright partagent la même pile TLS, leurs valeurs JA4 coïncident donc.
Ce qui les sépare est ailleurs : le drapeau webdriver, les surfaces de navigateur manquantes, le
rythme des requêtes, et le fait que le client charge ou non les feuilles de style et les polices
qu'un navigateur chargerait. L'empreinte est donc une entrée et non le verdict, un point déjà
abordé dans
les meilleurs signaux pour la détection de bots.
Là où elle cesse d'être une preuve
Deux limites comptent, et les deux sont volontiers escamotées dans la prose commerciale.
Une empreinte désigne un groupe, pas une identité. Chaque Chrome 141 sous Windows envoie en pratique le même client hello. Cela fait des millions de personnes derrière une seule chaîne. Vous pouvez dire "cette connexion venait de quelque chose ayant la forme de Chrome 141", et vous ne pouvez rien dire de qui. Traitez une valeur JA4 comme un identifiant de visiteur et vous vous tromperez sans arrêt, dans les deux sens.
Les empreintes se copient. uTLS permet à un programme Go d'émettre un client hello identique octet pour octet à une version de Chrome choisie. curl-impersonate fait la même chose pour curl. Quiconque est assez motivé pour lire un article peut faire présenter à son scraper une empreinte de navigateur parfaitement banale. Ce que cela coûte, c'est de l'effort, et l'effort est un vrai filtre : la différence entre un script qui s'est donné cette peine et un script qui ne l'a pas fait représente l'essentiel de l'automatisation sur internet. Mais un acteur déterminé franchit ce signal, donc tout dispositif qui repose sur JA4 seul le laissera passer.
Il existe un troisième problème, plus discret. Les proxys d'entreprise qui inspectent TLS réécrivent le client hello, et tous les employés derrière partagent donc l'empreinte du proxy plutôt que celle de leur navigateur. Bloquer sur une empreinte peut vous faire perdre une entreprise entière d'un coup.
L'utiliser avec les autres signaux
Ce qui tient, c'est l'empilement, pas le classement. Chaque signal répond à une question différente :
| Signal | Question à laquelle il répond | Échoue quand |
|---|---|---|
| JA4 | Quelle pile TLS est-ce ? | Le client utilise uTLS, ou se trouve derrière un proxy d'inspection |
| Origine IP | D'où vient la connexion ? | L'opérateur loue des adresses résidentielles |
| Marqueurs headless | Un navigateur est-il piloté ? | L'outillage corrige ses propres indices |
| Cohérence des en-têtes | Les affirmations concordent-elles ? | La requête a été assemblée à la main avec soin |
| DNS inverse et ASN | Ce crawler est-il bien celui qu'il prétend ? | L'opérateur ne publie rien de vérifiable |
Lisez la colonne "échoue quand" de haut en bas et le point devient évident : les contournements diffèrent pour chaque ligne. En battre un est facile, les battre tous les cinq à la fois est un projet. Une IP de datacenter, plus une empreinte Go, plus un User-Agent Chrome, cela n'a rien d'ambigu. Une IP résidentielle avec une vraie empreinte Chrome et aucun indice headless est probablement une personne, et mérite d'être traitée comme telle.
C'est la logique sur laquelle tourne Agentscan. Un seul POST renvoie une classe,
human, known_bot, ai_agent ou malicious_automation, avec une valeur de confiance et les
signaux sous-jacents, JA4 compris. Les verdicts en cache reviennent en moins de 50 ms, ce qui
permet de placer le contrôle dans un passage de middleware plutôt que dans une revue de logs le
lendemain matin.
Une politique praticable
- Récupérez l'empreinte là où TLS se termine. Le code applicatif ne voit jamais le client hello. Elle vient de votre CDN, de votre load balancer ou d'une API de détection placée devant.
- Notez l'écart, pas l'empreinte. Le signal est "la pile TLS ne correspond pas au navigateur revendiqué", pas "ce hachage est mauvais". Maintenir une liste de blocage de hachages vieillit mal, puisque chaque version de navigateur en produit de nouveaux.
- Ne la laissez jamais décider seule. Associez-la au minimum à l'origine. Seule, elle attrapera un proxy d'entreprise et manquera un scraper compétent, soit deux fois le mauvais résultat.
- Attendez-vous à voir bouger les valeurs. Les mises à jour des navigateurs changent les jeux de suites de chiffrement et d'extensions. Ce que vous figez aujourd'hui demande une date de revue, sinon cela finit par signaler discrètement de vrais utilisateurs.
- Journalisez-la dans tous les cas. Même sans agir dessus, stocker le JA4 avec chaque requête rend le prochain incident lisible. Constater que 40 000 requêtes partageaient une empreinte inhabituelle est un point de départ bien plus rapide que la lecture de logs bruts.
En résumé
JA4 vous dit comment un client parle TLS, ce qui est plus difficile à falsifier par négligence que n'importe quel en-tête et plus facile à falsifier délibérément que la plupart des fournisseurs ne l'admettent. C'est un signal fort sur la forme du logiciel à l'autre bout, un signal faible sur l'intention, et aucun signal sur l'identité. Servez-vous-en pour attraper l'automatisation qui n'a jamais tenté de paraître humaine, empilez-le avec l'origine IP et les marqueurs headless pour celle qui a essayé, et ne bâtissez pas une règle de blocage qui repose sur lui seul.
FAQ