4 points par GN⁺ 2026-03-30 | 1 commentaires | Partager sur WhatsApp
  • Lors de l’envoi d’un message dans ChatGPT, le programme Cloudflare Turnstile s’exécute et inspecte non seulement l’empreinte du navigateur, mais aussi l’état de l’application React
  • Le programme déchiffré collecte 55 propriétés et applique une procédure de vérification en trois couches : navigateur, réseau et application
  • La vérification ne peut être réussie que dans un véritable environnement SPA où le rendu React est terminé, ce qui signifie que les navigateurs headless et les simples requêtes de bot échouent
  • L’empreinte collectée est chiffrée puis convertie en OpenAI-Sentinel-Turnstile-Token, auquel s’ajoutent ensuite les modules Signal Orchestrator et Proof of Work
  • Comme seuls les serveurs de Cloudflare connaissent la clé de déchiffrement, la frontière de confidentialité est définie par la politique plutôt que par la technique

Analyse du fonctionnement de Cloudflare Turnstile lors de l’envoi d’un message dans ChatGPT

  • À chaque envoi de message dans ChatGPT, le programme Cloudflare Turnstile s’exécute automatiquement dans le navigateur
    • L’analyse de 377 programmes Turnstile déchiffrés à partir du trafic réseau montre qu’il ne se limite pas à une collecte classique d’empreinte navigateur, mais inspecte aussi l’état de l’application React
    • Les bots qui ne font que falsifier l’empreinte du navigateur ne passent pas la vérification ; il faut rendre complètement la SPA (application monopage) de ChatGPT pour la réussir

Structure de chiffrement et processus de déchiffrement

  • Le bytecode Turnstile est transmis dans le champ turnstile.dx de la réponse serveur et il est chiffré à chaque requête sous la forme d’une chaîne base64 de 28 000 caractères
    • La couche de chiffrement externe peut être déchiffrée par une opération XOR avec le jeton p, les deux valeurs étant échangées dans la même requête HTTP
    • Le résultat déchiffré est un bytecode JSON composé de 89 instructions de VM
  • À l’intérieur se trouve un blob chiffré supplémentaire de 19 KB, lui aussi chiffré avec une autre clé XOR
    • La clé est incluse dans le bytecode sous la forme d’une valeur littérale flottante (par ex. 97.35), générée par le serveur puis envoyée au navigateur
    • Sur 50 requêtes, un déchiffrement valide en JSON a été confirmé selon le même procédé
  • La procédure complète de déchiffrement se compose des 5 étapes suivantes
    1. Lire le jeton p dans la requête
    2. Lire turnstile.dx dans la réponse
    3. XOR(base64decode(dx), p) → génération du bytecode externe
    4. Extraire la dernière valeur comme clé depuis l’instruction à 5 arguments située après le blob de 19 KB
    5. XOR(base64decode(blob), str(key)) → déchiffrement du programme interne (417 à 580 instructions)

Éléments inspectés par le programme déchiffré

  • Le programme interne s’exécute sur une VM personnalisée avec 28 instructions (opcodes), et les adresses des registres flottants changent aléatoirement à chaque requête
  • Il collecte au total 55 propriétés, identiques dans les 377 échantillons
  • Couche 1 : empreinte du navigateur

    • 8 propriétés liées à WebGL : UNMASKED_VENDOR_WEBGL, UNMASKED_RENDERER_WEBGL, WEBGL_debug_renderer_info, etc.
    • 8 informations d’écran : colorDepth, pixelDepth, width, height, availWidth, availHeight, availLeft, availTop
    • 5 éléments matériels : hardwareConcurrency, deviceMemory, maxTouchPoints, platform, vendor
    • 4 mesures de police : création d’un div caché puis mesure de la taille de rendu via fontFamily, fontSize, getBoundingClientRect, innerText
    • 8 éléments d’exploration du DOM : createElement, appendChild, removeChild, style, position, visibility, ariaHidden, etc.
    • 5 éléments de stockage : storage, quota, estimate, setItem, usage
      • Les résultats sont stockés dans localStorage sous la clé 6f376b6560133c2c afin de persister entre les rechargements de page
  • Couche 2 : réseau Cloudflare

    • 5 en-têtes edge : cfIpCity, cfIpLatitude, cfIpLongitude, cfConnectingIp, userRegion
    • Ces valeurs n’existent qu’au sein du réseau Cloudflare ; les bots accédant directement au serveur d’origine obtiennent donc des champs absents ou incohérents
  • Couche 3 : état de l’application

    • 3 structures internes React : __reactRouterContext, loaderData, clientBootstrap
    • Ces éléments n’existent que lorsque l’application React de ChatGPT a été entièrement rendue et que l’hydratation SSR est terminée
    • Les navigateurs headless qui ne chargent que le HTML ou n’exécutent pas les bundles JS, ainsi que les frameworks de bots qui n’exécutent pas réellement React, échouent

Processus de génération du jeton

  • Après la collecte des 55 propriétés, le programme déchiffre un blob chiffré de 116 octets puis exécute 4 instructions finales
    • JSON.stringify(fingerprint)storeXOR(json, key)RESOLVE
    • La valeur obtenue est convertie en en-tête OpenAI-Sentinel-Turnstile-Token et incluse dans toutes les requêtes de conversation

Composants supplémentaires de Sentinel

  • En plus de Turnstile, deux modules de vérification supplémentaires sont présents
  • Signal Orchestrator

    • Composé de 271 instructions
    • Installe des écouteurs d’événements keydown, pointermove, click, scroll, paste, wheel
    • Suit 36 propriétés window.__oai_so_* afin de surveiller le timing de frappe, la vitesse de la souris, les schémas de défilement, le temps d’inactivité et les événements de collage
    • Il joue le rôle d’une couche biométrique comportementale en plus de la collecte d’empreinte
  • Proof of Work

    • Basé sur une empreinte de 25 champs + SHA-256 hashcash
    • La difficulté est un nombre aléatoire uniforme dans une plage de 400K à 500K ; 72 % sont résolus en 5 ms ou moins
    • Il inclut 7 indicateurs binaires de détection : ai, createPRNG, cache, solana, dump, InstallTrigger, data (tous à 0 dans 100 échantillons)
    • Il ajoute un coût de calcul, mais ne constitue pas le principal moyen de défense

Qui peut déchiffrer le jeton et implications de sécurité

  • Comme la clé XOR du programme interne est générée par le serveur puis intégrée au bytecode, seul le serveur qui a généré turnstile.dx connaît cette clé
  • La frontière de confidentialité entre l’utilisateur et l’opérateur du système est définie par une décision de politique, et non par une contrainte cryptographique
  • L’objectif de l’obfuscation est de
    • masquer les éléments collectés contre l’analyse statique
    • empêcher l’exploitant du site (OpenAI) de lire directement les valeurs brutes de l’empreinte
    • rendre chaque jeton unique afin d’éviter la réutilisation (replay)
    • rendre difficile la détection externe des changements opérés par Cloudflare sur les éléments inspectés
  • Cependant, le chiffrement repose sur une opération XOR avec la clé dans le même flux de données, ce qui n’est qu’une obfuscation destinée à compliquer l’analyse

Statistiques de collecte et d’analyse

Élément Valeur
Programmes déchiffrés 377/377 (100 %)
Utilisateurs uniques observés 32
Nombre de propriétés par programme 55 (identiques pour tous)
Nombre d’instructions 417–580 (moyenne 480)
Clés XOR (50 échantillons) 41
Propriétés de Signal Orchestrator 36
Champs de Proof of Work 25
Temps de résolution du PoW 72 % en 5 ms ou moins

Méthodologie d’analyse

  • Seul du trafic collecté selon une procédure légale a été utilisé
  • Aucune donnée personnelle d’utilisateurs n’a été publiée
  • Tout le trafic a été observé avec le consentement des participants
  • Le SDK Sentinel (sdk.js, 1 411 lignes) a fait l’objet d’une désobfuscation manuelle et d’un déchiffrement hors ligne
  • Le déchiffrement a été réalisé hors ligne en Python

1 commentaires

 
GN⁺ 2026-03-30
Commentaires sur Hacker News
  • Bonjour, je m'appelle Nick et je travaille dans l’équipe Integrity d’OpenAI
    Cette vérification fait partie des mesures de protection visant à empêcher les abus de la plateforme, comme les bots, le scraping ou la fraude
    L’objectif est de continuer à offrir l’accès aux utilisateurs gratuits et non connectés tout en priorisant les ressources GPU pour les vrais utilisateurs
    Nous surveillons le temps de chargement des pages, le délai avant le premier token, la taille des payloads, etc., et nous nous concentrons sur la réduction maximale de la surcharge induite par ces protections
    L’impact est minime pour la plupart des utilisateurs, et seul un très petit nombre pourrait subir un léger ralentissement
    Nous continuons aussi à évaluer des améliorations de précision afin de réduire les faux positifs tout en rendant les abus plus difficiles

    • Il est intéressant qu’OpenAI considère le scraping comme un abus
    • On en arrive à une situation où il faut un navigateur qui accepte toutes les vérifications côté client pour utiliser les services essentiels, et un autre navigateur pour se protéger du pistage
      Je comprends l’explication de Nick, mais je me demande si nous allons continuer à vivre dans un monde où il faut choisir entre vie privée et fonctionnalité
    • Je ne sais pas si c’est lié, mais dans les longues conversations, les performances de l’interface Chat se dégradent fortement
      Il y a de la latence à la saisie, des saccades de rendu, voire des blocages complets
      Je constate la même chose sur Safari de l’iPhone 16 et sur Chrome d’un MacBook Pro M3
    • Un nouveau compte n’a laissé que deux commentaires, donc on peut se demander comment savoir s’il s’agit vraiment d’un humain ou d’un bot qui défend OpenAI
      Il y a aussi une suggestion mi-sérieuse, mi-plaisante, de lancer les outils intrusifs de Cloudflare et de partager le résultat
    • C’est appréciable d’avoir une réponse directe de quelqu’un d’OpenAI
      Je suis abonné Pro et mon équipe dépense plus de 2 000 dollars par mois
      Mais quand j’utilise un VPN (Mullvad), l’interface Chat se coupe souvent ou expire, même en étant connecté
      Ce serait bien que les utilisateurs payants puissent l’utiliser de manière stable, avec ou sans VPN
  • Une plainte affirme que Cloudflare rend le web presque inutilisable en raison de navigateurs ou d’IP jugés « suspects »
    La personne dit être tombée dans un enfer de CAPTCHAs simplement parce qu’elle utilise Firefox

    • La définition de « suspect » chez Cloudflare ne cesse de s’élargir
      Les VPN, les navigateurs axés sur la confidentialité, les plages d’IP rares et autres utilisateurs soucieux de leur vie privée sont justement ceux qui se retrouvent le plus ciblés
      Pendant ce temps, les bots contournent facilement ce type de filtres
    • Quelqu’un suggère de vérifier si un trafic web inconnu ne sort pas du réseau
      Cette personne utilise aussi Firefox, mais ne voit qu’un niveau normal de CAPTCHAs
    • J’utilise la combinaison Firefox + Ublock Origin et je ne vois presque jamais de CAPTCHA
      J’ai désactivé le CGNAT, donc je me demande si cela fait une différence
    • Une personne partage l’expérience absurde d’avoir dû résoudre 15 CAPTCHAs d’affilée juste après un paiement
      La banque avait déjà vérifié son identité, donc elle trouve difficile à comprendre qu’un site soit incapable de distinguer un humain d’un bot
  • Comme OpenAI propose ChatGPT gratuit aux utilisateurs non connectés, il semble logique qu’ils cherchent à empêcher qu’il soit détourné comme une API gratuite

    • Quelqu’un se demande si cette vérification s’applique aussi aux utilisateurs connectés
      Dans l’application Android, il y a un contrôle Play Integrity, alors que l’app Claude demande seulement une connexion sans ce type de vérification
    • Une personne raconte avoir utilisé ChatGPT sans se connecter
      Elle a été surprise d’obtenir une réponse en entrant simplement une question, sans cookie ni compte
    • Ce type de protection vise aussi à préserver les usages des abonnés Pro
      Le modèle d’abonnement revient bien moins cher que l’API, donc il faut limiter les abus
      Un simple contrôle au chargement d’une SPA ne constitue pas un gros obstacle, et ceux qui en ont conscience ont déjà les compétences pour le contourner
      D’autres entreprises mettent elles aussi en place leurs propres systèmes anti-bot
    • Utiliser GPT‑5.2 pour 20 dollars par mois offre un rapport qualité-prix exceptionnel, donc une révision tarifaire finira sans doute par arriver
    • Il semble que copilot.microsoft.com utilise lui aussi une protection similaire basée sur Cloudflare
  • Il est intéressant que certaines propriétés n’existent que lorsque l’application React de ChatGPT est entièrement rendue
    Cela signifie qu’il s’agit d’une détection de bots au niveau de la couche applicative, et non du navigateur
    Je pensais que la plupart des systèmes de détection avancés fonctionnaient déjà ainsi, donc je me demande ce que cette découverte a de particulièrement notable

  • Quelqu’un aurait aimé que l’auteur explique plus clairement pourquoi ce point devrait être important
    Au fond, OpenAI veut simplement que les utilisateurs passent par l’application React officielle, et il n’est pas évident en quoi cela pose problème

    • C’est pourquoi le texte lui a semblé être un article médiocre écrit par une IA
  • D’un point de vue technique, c’est intéressant
    Turnstile est censé fonctionner sans configuration propre à chaque site, donc on se demande comment OpenAI a pu combiner les données de Turnstile avec sa propre API

  • Quelqu’un dit ne pas comprendre pourquoi les opérateurs de bots ne lancent pas simplement des VM Windows 11 + Chrome
    Avec la déduplication mémoire, on pourrait faire tourner 50 VM en parallèle, et sur AWS cela reviendrait à environ 1 centime pour 1 000 chargements de page, donc ce serait très bon marché

    • Il existe déjà de nombreux services packagés qui proposent ce genre de fonctionnalités
      Rotation d’IP, usurpation de localisation, réglages de langue, parseurs intégrés, etc. : les options sont variées et le coût de changement est faible, donc il y a peu d’intérêt à tout construire soi-même
    • En pratique, cette approche à base de VM a un effet dissuasif en réduisant le nombre de bots, car elle coûte beaucoup plus cher que les méthodes les plus simples
    • Dans les communautés Reddit consacrées au scraping, les développeurs de bots se montrent très frustrés lorsqu’un accès en navigateur headless est bloqué
      Comme suggéré, utiliser des conteneurs Linux au lieu de Windows serait bien plus léger et efficace
    • Quelqu’un demande s’il existe un moyen simple de faire tourner une VM Windows 11 avec une bonne accélération graphique sans passthrough GPU
  • Critique d’un article bâclé qui semble avoir été rédigé par ChatGPT

    • Blague : « L’une des caractéristiques traditionnelles des blogs web, c’est que les brouillons sont si mauvais qu’un modèle de langue doit encore faire une deuxième passe de révision »
  • Quelqu’un dit avoir utilisé en 2023~2024 une extension appelée KeepChatGPT
    Il trouvait intéressant qu’elle fonctionne en se faisant passer pour un utilisateur, sans API
    Il a ensuite arrêté de l’utiliser à cause de l’arrivée de Gemini et des erreurs fréquentes, mais il appréciait l’option permettant de déplacer le panneau IA sur la droite
    Lien GitHub de KeepChatGPT

    • Cette personne utilise un petit utilitaire basé sur WinForms WebView pour envoyer des requêtes à ChatGPT et recevoir des réponses JSON
      Cette méthode ne déclenche pas du tout le système anti-bot d’OpenAI
  • Question sur le fait de savoir si l’intégration entre Cloudflare et l’application relève de fonctionnalités personnalisées au-delà du Turnstile standard, ou s’il s’agit d’une option réservée à l’édition Enterprise