Reverse engineering · Octobre 2026

BotGuard : ce que nos tests révèlent
sur les protections de Google

Quels navigateurs obtiennent des résultats, ce que change la session, ce que les scripts de Google inspectent dans le navigateur, et pourquoi une page de résultats reçue n’est pas forcément un relevé fiable.

Le logo Google dans un bouclier, entouré de bots
Powered by RESONEO

Depuis l’été 2026, Google a modifié le contrôle qui tourne en tâche de fond sur ses pages de résultats. Entre le 20 et le 22 août, il y a ajouté quatre familles de tests : réglages déclarés par le navigateur, rendu du texte, précision du pointeur et carte graphique via WebGPU. Le test WebGPU a disparu le 5 octobre. Depuis juillet, une partie des requêtes reçoit en plus un module qui conserve un historique d’interactions dans le navigateur et le relit au passage suivant. Fin août, Google a aussi généralisé les liens de redirection /goto dans ses résultats.

Les essais de navigateurs depuis un VPS, sur IP native et sorties VPN, et l’analyse du code servi par Google décrivent jusqu’à quatre machines virtuelles (VM) sur une même page de résultats, trois parcours de contrôle distincts. Dans la comparaison contrôlée du même Chrome, le refus suit la valeur native de navigator.webdriver, indépendamment du réglage de lancement qui l’active habituellement. Le signal d’automatisation et l’état de la session influencent les parcours observés ; l’IP seule n’explique pas les écarts. Et une page de résultats obtenue ne garantit pas un relevé fiable.

L’expérience interactive SearchGuard — Episode II
The Empire Scrapes Back
La même enquête, jouée en sept actes. Passez vous-même le contrôle de Google, voyez ce que votre navigateur raconte de vous, et ce qui décide que vous obtenez les résultats — ou pas. Entrer dans l’expérience →

Sommaire

Partie I

Les retours terrain

Quelles configurations obtiennent des résultats ? Quel rôle joue la session ? Peut-on se fier au classement reçu ?

1

Ce qui est en jeu : qui peut observer les résultats de Google

Les pages de résultats de Google sont plus qu’un service : elles reflètent ce que le monde cherche, minute après minute. Toute une industrie y mesure sa visibilité. Les protections décrites dans cette page décident qui a le droit de regarder.

Le marché dépend de cette fenêtre

Chaque rapport de positions, chaque indicateur de visibilité, chaque outil qui dit à une entreprise où elle en est repose sur la lecture des pages de résultats de Google. Le procès antitrust du DoJ contre Google a abouti en 2024 au constat d’un monopole sur la recherche généraliste : il n’existe pas de source de remplacement. Ce qui se passe sur ces pages, c’est le marché.

Les nouveaux venus de l’IA ont fait monter les enjeux

Depuis 2024, des entreprises d’IA puisent massivement dans les résultats de Google pour alimenter leurs propres réponses, sans l’accord de Google. Lors du procès antitrust américain, un dirigeant d’OpenAI a déclaré sous serment qu’OpenAI avait demandé l’accès à l’index de Google et s’était vu refuser. Depuis, de nombreux chercheurs indépendants, dont nous, ont montré que les réponses de ChatGPT se construisent en partie sur des résultats de Google. Les protections décrites dans cette page défendent aussi Google face à ses concurrents les plus récents.

Google éteint la lumière, interrupteur par interrupteur

La chronologie de la partie II montre la séquence : la fin des 100 résultats par page (septembre 2025), des liens de redirection sur chaque résultat (août 2026), quatre nouveaux contrôles du navigateur (août 2026) et un module qui garde des données d’un passage à l’autre (juillet 2026). Aucune annonce, aucun numéro de version. Chaque étape rend l’observation indépendante plus difficile et plus coûteuse.

Les régulateurs ordonnent l’inverse

Pendant que la pièce s’assombrit, les tribunaux et les régulateurs cherchent l’interrupteur. Dans l’affaire antitrust américaine, le tribunal a ordonné à Google de partager des données de recherche avec des concurrents qualifiés (septembre 2025). En Europe, le règlement sur les services numériques (DSA) donne aux chercheurs agréés un droit d’accès aux données des très grands moteurs de recherche. Ce que le code de Google éteint, la loi commence à rallumer.

Ce que les gens cherchent est produit par le public. Aujourd’hui, une seule entreprise décide qui peut l’observer.

2

Accéder aux résultats : ce qui passe, ce qui bloque

Dans les essais contrôlés, le refus suit la valeur native de navigator.webdriver. À Chrome, machine et réseau constants, les résultats s’affichent lorsque cette propriété vaut false, même avec le réglage --enable-automation. Lorsqu’elle vaut true, le navigateur est refusé, même sans ce réglage. Le réglage de lancement et le signal exposé à la page peuvent donc être distingués expérimentalement.

ConfigurationSe déclare automatiséSortie réseauParcours observé
Client HTTP sans JavaScriptSans objetVPN comparéeReste sur le challenge
Chrome lancé normalement, recherche tapée au clavierNonIP nativeRésultats après challenge
Même Chrome + le seul réglage --enable-automationOuiIP nativeRefus
Chrome piloté par Playwright, avec interfaceOuiIP native et VPNRefus
Chrome piloté par Playwright, headlessOuiVPN comparéeRefus
Camoufox · profil neufNonIP native et VPNRésultats après challenge
Camoufox · session conservéeNonVPN fixe, essais de sessionRésultats directs

La ligne de partage suit la déclaration d’automatisation. L’IP seule ne suffit pas à expliquer les différences : sur IP native comme sur VPN, Camoufox obtient des résultats là où Chrome piloté par Playwright est refusé, et le même Chrome lancé normalement passe sur l’IP native.

Le réglage de lancement ou le signal exposé à la page ?

La comparaison croise deux facteurs : la présence de --enable-automation et la valeur native de navigator.webdriver. Les quatre combinaisons sont répétées dans deux blocs d’ordre randomisé, avec un profil neuf à chaque navigation. Deux témoins Chrome ordinaires encadrent la série et affichent tous deux les résultats.

Chrome 153 · même binaire, mêmes IPv4 et IPv6 · deux essais par combinaison
--enable-automationnavigator.webdriverRésultat
Absentfalse2 / 2 résultats
Présentfalse2 / 2 résultats
Absenttrue2 / 2 refus
Présenttrue2 / 2 refus

Le getter JavaScript reste natif : la valeur est contrôlée par le navigateur, sans remplacer la propriété dans la page. La fonctionnalité Blink AutomationControlled est désactivée dans les quatre combinaisons ; une commande CDP règle le signal indépendamment du flag. Knitsail et la VM YouTube lisent cette propriété (voir les lectures observées). Le résultat soutient un rôle causal du signal natif dans cet environnement, sans révéler le score serveur ni établir une règle universelle.

La décision tombe juste après la page de vérification

Parcours du test avec le réglage seul, sans intervention sur la valeur native :

Chrome · lancé normalement

Ne se déclare pas automatisé

Page de vérification, 0,2 sRechargementRésultats
Chrome · même lancement + --enable-automation

Se déclare automatisé

Page de vérification, 0,2 sRechargementRefus et CAPTCHA

Sur les profils neufs observés, Google sert une page de vérification avant de recharger la recherche avec les éléments produits par le contrôle. Les traces du test du réglage seul situent ce rechargement environ 0,2 seconde après la réponse. Le document principal conduit ensuite soit aux résultats, soit à /sorry et à une réponse 429. La classification utilise la navigation principale, la présence des résultats et les captures d’écran ; une requête de fond vers /sorry ne suffit pas à classer la navigation comme refusée.

Dans la matrice contrôlée, la présence du flag ne distingue pas les résultats ; la valeur native de webdriver les distingue dans tous nos essais. Les témoins acceptés et les adresses IPv4 et IPv6 constantes limitent l’explication par un changement de réseau.

Deux essais par combinaison, sur une machine, un réseau et une requête : ces effectifs ne donnent pas un taux de réussite généralisable. Un remplacement du getter par du JavaScript retournant false a également été refusé ; cette intervention n’est donc pas un contrôle neutre. Protocole et contrôles complémentaires : signal d’automatisation et réglages de Chrome.

3

La session change le parcours

À navigateur et sortie réseau fixes, nous avons comparé des copies d’un même profil, en conservant ou en supprimant le cookie NID. Le contraste est reproduit : la session conservée évite le challenge, sa suppression le réintroduit.

Camoufox · même configuration

Session conservée

NID présentRésultats directs
Camoufox · même configuration

NID supprimé

Nouveau challengeRésultats

Repartir d’un profil vierge ou supprimer des cookies peut réintroduire un contrôle que la session conservée évitait.

Le retour du challenge n’est pas un échec : les résultats arrivent aussi après celui-ci. NID est associé ici à un effet de session ; SG_SS transporte un résultat du challenge. Ces observations ne font pas de NID un passe universel et ne mesurent pas la durée de validité de SG_SS.

4

Suspicion d’empoisonnement : deux listes pour une même requête

Même requête, même IP, deux listes sans URL commune. Ce contraste nourrit une suspicion d’empoisonnement des résultats par Google : des pages plausibles seraient servies à un client automatisé avec un contenu volontairement altéré.

GoogleRequête : musée du Louvre site officiel

Le 18 octobre 2026, les deux recherches démarrent à 2 minutes d’intervalle. Les profils sont deux copies du même profil source ; seul NID diffère parmi les cookies transmis. La branche conservant NID reçoit directement les résultats ; l’autre passe par un challenge.

Paire 06/07 · résultats principaux, hors sitelinks et modules
NID conservé
Résultats directs
6 résultats
  1. 1Accueil du Louvrelouvre.fr/
  2. 2Musée du LouvreMinistère de la Culture
  3. 3Compte Instagram du Louvre
  4. 4Louvre-Lens
  5. 5Page Facebook du Louvre
  6. 6Fiche du muséeParis je t’aime

Fin des résultats principaux

NID supprimé
ChallengeRésultats
9 résultats
  1. 1Premiers pas au LouvreRessource pédagogique
  2. 2Le musée du Louvre en brefEspace presse
  3. 3École du Louvre
  4. 4Compte X du Louvre
  5. 5Visite guidéeParis je t’aime
  6. 6Librairie-boutique du Louvre
  7. 7Accueil anglaislouvre.fr/en/
  8. 8FAQ billets et tarifs
  9. 9Parcours de visite

Sur fond bleu : l’accueil du site officiel, en français à gauche, en anglais à droite. Ce sont deux URL distinctes.

0 URL cible commune entre les 6 et les 9 résultats. La seconde liste met en avant des ressources pédagogiques, la presse, l’école, la boutique et la billetterie.

Sur l’ensemble de la série du 18 octobre, l’accueil du Louvre arrive le plus souvent septième, plus rarement premier, et manque parfois parmi les résultats principaux. Dans les branches qui conservent NID, les pages où il est septième enregistrent un appel Validate, 8 à 10 secondes après la réception de la page. L’ordre affiché est déjà fixé à ce moment-là : sur toutes les pages, l’ordre reçu correspond à l’ordre final.

Partie II

Sous le capot : le code et les traces

L’évolution de la protection, ses composants et les échanges observés. Le code décrit des capacités ; les traces montrent lesquelles ont été exécutées dans nos sessions.

5

Comment la protection a évolué

La protection s’enrichit sans changer de version majeure de BotGuard : page intermédiaire, contrôles en arrière-plan, reprise de requêtes, puis en 2026 de nouveaux tests du navigateur et un module qui garde des données d’un passage à l’autre. Les dates techniques sont celles des premières observations disponibles dans notre corpus, pas nécessairement celles du déploiement.

Mécanismes BotGuard et SearchGuard Changements qui touchent la collecte des SERP
  1. Première observation

    BotGuard version 41

    BotGuard est déjà en version 41. Ce numéro reste utilisé en octobre 2026, malgré la rotation des scripts et de leurs paramètres de chiffrement.

  2. Première observation · confirmé par Google

    Un parcours qui exige JavaScript

    Le code des résultats traite le paramètre sg_ss et prévoit un renvoi vers /httpservice/retry/enablejs lorsque JavaScript est désactivé.

    Google a confirmé l’exigence de JavaScript le 17 janvier 2025, en la présentant comme une protection contre les bots et le spam (TechCrunch).

  3. Première observation

    La page intermédiaire SearchGuard

    Une page intermédiaire embarque knitsail, produit le cookie SG_SS et relance la navigation. Ce mécanisme est établi au plus tard en mai 2025.

  4. Source presse
    Accès aux données · Coût du scraping

    Fin des 100 résultats par requête

    Google cesse de prendre en charge num=100. La collecte des 100 premières positions peut désormais nécessiter environ dix pages de résultats au lieu d’une.

    Arrêt constaté dans la nuit du 11 septembre 2025, rapporté le 15 septembre par Search Engine Land. Le 18 septembre, Google a déclaré ne pas prendre officiellement en charge ce paramètre.

  5. Première observation

    Un canal de livraison distinct

    Le canal /sgasync, associé au code BMW, livre ensemble le script, son hash et son programme. Il complète un parcours de protection déjà existant.

  6. Première observation

    Le contrôle en tâche de fond

    Le canal sg_ck=QyE sert au contrôle en tâche de fond, avec un programme distinct de celui de BMW.

  7. Première observation

    Un contrôle pendant une requête

    Avec le mode sg_ck=ON4, le client peut calculer un token puis réessayer une requête avec X-Sg-Ss. Ce parcours est distinct de la page intermédiaire.

  8. Première observation

    Du code pour les iframes

    Les moteurs intègrent des fonctions manipulant sandbox, srcdoc et le chargement de scripts. Knitsail reçoit aussi ces fonctions.

  9. Première observation

    Un module qui garde des données dans le navigateur

    Une partie des requêtes reçoit le programme du contrôle de fond augmenté d’un module d’environ 6 Ko. Ce module conserve un historique d’interactions dans le navigateur (localStorage) et le relit au passage suivant (structure et contenu). Les deux versions sont servies en même temps, pour une même adresse de requête.

    Observé du 8 juillet au 17 octobre 2026. En juillet, 10,5 % des captures contiennent ce module, toutes entre le 8 et le 16 ; ensuite, environ 1 %. Les données ne sont relues que par l’exemplaire de programme qui les a écrites. Test A/B, échantillonnage ou ciblage côté serveur : notre corpus ne permet pas de trancher.

  10. Première observation

    Quatre nouveaux tests dans le contrôle de fond

    Le programme du contrôle QyE lit des réglages déclarés par le navigateur (plateforme, « Do Not Track »), mesure la hauteur d’un texte avec et sans césure, teste la précision du pointeur (souris ou écran tactile) et interroge la carte graphique via WebGPU. Le programme décodé grossit d’environ 13 % (+2,6 Ko) ; le moteur qui l’exécute ne grossit pas.

    Apparition datée entre le 20 août à 12:06 et le 22 août à 20:58 UTC : notre corpus ne contient aucune capture entre ces deux moments, et les quatre tests arrivent ensemble. La taille du programme ne dit rien de son coût d’exécution ni de son efficacité contre les bots.

  11. Confirmé par Google
    Accès aux données · Résolution des URL

    Les URL passent par /goto

    Google déploie des liens de redirection /goto dans ses pages de résultats. L’URL finale doit parfois être résolue séparément. Une requête HTTP ordinaire suffit encore dans les cas documentés.

    Déploiement confirmé par Google à Search Engine Land le 26 août 2026, après plusieurs mois de tests selon le média.

  12. Première observation

    Un canal associé à Google Flights

    Le canal /sgasync associe sg_ck=QyE au paramètre sg_fe=flights.

  13. Première observation

    Le test de la carte graphique disparaît

    Le contrôle de fond cesse d’interroger la carte graphique via WebGPU. Les trois autres tests ajoutés en août restent en place. Le changement coïncide avec une nouvelle version du moteur JavaScript.

    Retrait daté entre 06:53 et 14:07 UTC le 5 octobre 2026. Notre session en direct du 17 octobre le confirme : navigator.gpu n’est plus lu. Le programme perd environ 320 octets.

Les jalons orange concernent la collecte des résultats. Ils sont distincts des mécanismes BotGuard. « Confirmé par Google » désigne une confirmation rapportée dans la source liée ; « Première observation » renvoie à nos captures de code et de pages.

6

Qui fait quoi dans le navigateur ?

SearchGuard est le nom employé par Google pour sa protection de Search. BotGuard est un moteur d’attestation côté navigateur : sa machine virtuelle (VM) exécute un programme fourni par Google. Le moteur et le programme sont deux objets distincts, qui peuvent évoluer séparément.

Une page de résultats Google

Résultats

/async/bgasy fournit l’adresse du script et le programme. La VM suit notamment les interactions avec les résultats. Aucun token de sortie n’a été repéré pendant ces sessions.

Knitsail

/sgasync livre ensemble le moteur et son programme. Ce contrôle inspecte le navigateur et envoie un token à Validate, sur les résultats classiques comme dans AI Mode.

Publicité

Une VM dans un cadre adtrafficquality.google produit un token pour le circuit publicitaire pagead/sodar.

YouTube intégré

Le lecteur embarqué apporte sa propre VM et des échanges avec le service Waa/GenerateIT. Sa présence dépend du contenu de la page.

Jusqu’à quatre VM ont coexisté sur une page observée. Elles ne remplissent pas toutes le même rôle : la publicité et YouTube ont leurs propres circuits. La copie du moteur de la page d’accueil a été analysée séparément, sans trace de ses lectures dans ces sessions.

Moteur, espaces de noms et obfuscation

Moteur, programme et obfuscation

Les trois VM des résultats, de knitsail et de la publicité observées le 17 octobre, ainsi que la copie de la VM d’accueil du 18 octobre, déclarent la version 41. La version de la VM YouTube n’a pas été relevée. Le nom de la fonction d’entrée tourne : pour les 26 programmes capturés le 17 octobre, ses trois premières lettres correspondent aux trois premiers caractères du programme encodé.

ÉlémentObservation
VersionLes scripts /js/bg/ et les VM incluses dans /sgasync étudiés déclarent la version 41.
Espaces de nomswindow.botguard pour les résultats et la publicité ; window.knitsail, constructeur ks, pour knitsail.
RegistresIndices relevés jusqu’à 511 dans la VM publicitaire et 484 dans knitsail : compatibles avec un espace de 512 emplacements. Le rôle de chaque indice n’est pas stable entre scripts.
ObfuscationIdentifiants courts, dispatch par états, calculs bit à bit, chaînes reconstruites à l’exécution. Des lignes vides aléatoires sont ajoutées au code évalué ; une source map factice porte le nom closureDynamicButton.
Hash des scriptsLe nom des fichiers /js/bg/ et publicitaires vérifiés correspond au SHA-256 en base64url du contenu. Pour les réponses /sgasync étudiées, le champ de hash correspond exactement au script inclus.
Iframes et sandboxLe code configure notamment sandbox, retire srcdoc et affecte une URL à l’iframe. Certaines autorisations y sont ajoutées, dont allow-same-origin et allow-scripts.
7

Les trois parcours de contrôle

Le contrôle peut intervenir avant les résultats, sur une page déjà affichée ou lors d’un appel supplémentaire. Ces trois parcours sont distincts : ils ne constituent pas une séquence obligatoire.

Avant les résultats

  1. Recherche → page intermédiaire
  2. Le programme s’exécute dans le navigateur
  3. Résultat transporté, notamment par le cookie SG_SS
  4. La recherche est relancée

En arrière-plan

  1. Une page de résultats est déjà affichée
  2. /sgasync livre moteur et programme
  3. Le navigateur calcule un token
  4. Le token est envoyé à Validate

Pendant une requête

  1. Une réponse demande un contrôle : X-Sg-Cs:s
  2. Le client calcule un token
  3. Nouvel essai avec l’en-tête X-Sg-Ss
  4. La capture montre ensuite X-Sg-Cs:a

Si le parcours aboutit à un refus : une redirection vers /sorry peut conduire à un reCAPTCHA. Dans les captures étudiées, cette redirection efface SG_SS. Le serveur reste décisionnaire ; une page HTTP 200 peut aussi être un challenge.

La reprise avec X-Sg-Ss est réellement capturée. En revanche, ni une réponse vide de Validate ni la production d’un token ne révèlent le verdict interne du serveur.

En-têtes, modes et branches du client

En-têtes et reprise des requêtes

Le client installe une couche autour de fetch et de XMLHttpRequest pour les requêtes de même origine. Une première couche met des réponses en attente dans __sg_lite_queue ; une seconde les traite quand elle est prête. Les valeurs ci-dessous décrivent le protocole observé ; aucune n’est un score de confiance.

NomSens établi par le code
x-sg-eValeurs observées : 2,isrpe=1,hcs=1 dans le corpus initial et 1,isrpe=1,hcs=1 dans la reprise VPS du 18 octobre. Le client conserve le mode 1 quand l’appelant l’a demandé ; sinon il utilise 2. Il ajoute des indicateurs de capacités.
isrpeDérivé de isrpeEnabled ou de window.sglc.isrpe. Il participe à la décision de recharger la page pour un contrôle synchrone ; le libellé interne exact de l’acronyme n’est pas publié.
hcsDérivé de hasCaptchaSupport ou de window.sglc.hcs : capacité du client à prendre en charge le CAPTCHA.
X-Sg-CsEn-tête de réponse. Le client distingue les valeurs commençant par s (branche synchrone) et a (événement asynchrone). Un chemin de reprise teste exactement s et a. Le préfixe sfl reçoit un traitement particulier.
X-Sg-SsPorte le token calculé lors de la reprise d’une requête. Il s’agit d’un en-tête, distinct du cookie SG_SS de la page intermédiaire.
X-Sorry-RedirectSa présence, ou une URL de réponse contenant /sorry/index, déclenche le traitement du parcours CAPTCHA.

Dans le chemin de reprise étudié, les codes internes 0, 1, 2 et 3 sélectionnent respectivement : calcul d’un token et nouvel essai ; événement sglacte ; attente d’un événement sglhcte_retry après sglhcte ; restitution de la réponse sans ce traitement. Ce sont des codes de branchement locaux, sans lien avec un niveau de risque.

Modes et interrupteurs du client

Le code distingue le contrôle demandé par une requête (ON4) d’un chargement non synchrone (BMW). Les captures montrent aussi le canal de fond QyE. Les noms courts sont des identifiants opaques : leur rôle se déduit des appels et des observations ; nous n’interprétons pas leurs lettres.

Dans le client d’octobre examiné, la configuration est issue de bits du tableau x. Les noms ci-dessous sont locaux à cette copie et peuvent tourner avec l’obfuscation. Leur présence montre ce que le code sait faire, sans dire si ces branches sont activées.

Interrupteur localEffet de la branche
ObAutorise le parcours de démarrage dans setup().
QbChoisit le démarrage synchrone ; l’autre branche attend une seconde puis un créneau inactif.
DdSur changement de visibilité, peut produire le résultat quand la page devient cachée.
BdCourt-circuite dans cette branche la récupération du résultat de la VM.
Cd / vcLe premier conditionne l’envoi ; le second choisit le chemin /sgvalid au lieu de Validate.
bd / cdPeuvent différer l’envoi jusqu’au rappel DOMContentLoaded, ou ajouter un délai de 1 000 ms. Présence de branches, sans preuve qu’elles aient été activées pendant les sessions.
Lc / zdContrôlent deux chemins de télémétrie distincts : journal d’étapes et mesures de durée.
8

Ce que chaque programme observe

Cette matrice résume les lectures et les listeners observés pendant l’instrumentation. « Non observé » ne signifie pas que le moteur en est incapable : le programme reçu et la session déterminent ce qui s’exécute.

SignalRésultatsKnitsailPublicitéYouTube
Clics et contacts tactilesOuiOuiNon observéOui
Souris, clavier, moletteNon observéOui, dont positions de certains événements sourisNon observéListeners ; positions souris non lues
Navigateur et écranTrès limité : window.scrollbarsPropriétés du navigateur et dimensionsQuelques propriétés selon le programmeInspection étendue
Indices d’automatisationNon observéwebdriver, window.chromeParfois window.chromewebdriver, window.chrome
Inventaire des noms globauxOuiOuiNon observéNon observé
WebGL / GPUNon observéNon observéNon observéNom du GPU
Visibilité de l’ongletOuiNon observéOuiOui, et focus
Mesure du tempsOuiOuiOuiOui
Inspection du code et des propriétésSon propre codeFonctions et accesseurs du navigateurNon observéPropriétés du navigateur

Knitsail et la VM YouTube inspectent l’environnement plus largement que les deux autres VM. Mais ces lectures ne révèlent ni les coefficients, ni les seuils, ni le modèle de décision de Google.

Ce que le contrôle de fond lit depuis fin août

Depuis le 22 août 2026, le programme du contrôle de fond lit aussi des réglages déclarés par le navigateur (navigator.platform, navigator.doNotTrack, window.doNotTrack). Il crée des blocs de texte cachés, en police à chasse fixe, et compare leur hauteur avec et sans césure automatique (hyphens). Il demande au navigateur si le pointeur est précis ou grossier (any-pointer: fine et coarse) : souris ou écran tactile. Jusqu’au 5 octobre, il interrogeait aussi la carte graphique via WebGPU (requestAdapter, puis fabricant et architecture).

Ces lectures sont relevées en exécutant hors ligne les programmes récoltés, de novembre 2025 au 17 octobre 2026. Notre session en direct du 17 octobre confirme la lecture des réglages et le test du pointeur, ainsi que l’absence de WebGPU. Détail : contrôle de fond, novembre 2025 à octobre 2026.

La matrice contrôlée distingue le réglage de lancement du signal natif navigator.webdriver : dans tous nos essais, le résultat suit la valeur du signal. Elle ne permet pas d’attribuer le verdict serveur à une lecture particulière d’une VM (voir les essais d’accès).

Un historique d’interactions dans le navigateur

La variante du contrôle de fond équipée du module localStorage conserve des enregistrements d’interactions et les relit lors d’une exécution suivante. Sur le programme du 18 août, une chaîne de 21 passages avec des clics distincts laisse exactement les 20 derniers enregistrements, dans leur ordre : le plus ancien est retiré. Il s’agit de vingt exécutions du programme, pas de vingt clics dans une page.

Dernier clic

Les champs de coordonnées conservent le dernier clic observé. Un clic en (123, 234), suivi d’un déplacement en (500, 400), laisse (123, 234). Un déplacement seul ne renseigne pas ces champs.

Compteurs d’événements

Un bloc contient 32 compteurs d’un octet dans les cas testés. Une frappe active trois compteurs ; trois frappes les portent à 3. Les touches « a » et « b » produisent le même contenu : ce bloc décrit les événements observés, sans y distinguer ces caractères.

Format binaire et évolution du stockage

Les programmes de juillet à octobre partagent tous la même structure : enveloppe de 8 octets ; contenu décodé avec marqueur 01 be ef, bloc de 12 octets, enregistrements et compteur final. Chaque enregistrement comporte un horodatage sur 4 octets, un champ d’un octet observé à 1, une longueur sur 2 octets et une charge utile variable. Le rôle du bloc de 12 octets et du champ égal à 1 reste indéterminé.

Sans interaction, la charge utile mesure 114 octets : le total binaire vaut 24 + 121 × n octets pour n enregistrements, soit 145 pour un seul et 2 444 pour vingt. Les interactions allongent la charge utile ; cette formule ne s’applique donc pas à tous les scénarios. Les horodatages de tous nos exemplaires correspondent à la capture du programme à une seconde près, et non à la date de visite simulée.

Le recensement de 134 états montre dix suffixes numériques de clé en juillet et un encodage base64 avec remplissage en juillet–août. Les exemplaires de septembre–octobre utilisent une clé sans suffixe et du base64 URL-safe sans remplissage. Le changement est encadré par nos captures du 18 août et du 28 septembre ; sa date exacte de déploiement reste inconnue.

La structure est observée sur tous les programmes décodés ; les interventions sur les clics, les compteurs et la file à vingt passages concernent celui d’août. Ces résultats ne démontrent ni un identifiant personnel stable, ni un suivi intersites, ni l’usage de cet historique dans le score serveur. Détails du contrôle de fond et du stockage.

L’instrumentation peut elle-même modifier les propriétés inspectées. Les comparaisons de contrôle et les replays documentent certaines perturbations ; ils ne prouvent pas que l’observation soit invisible pour Google.

9

Du programme reçu au token envoyé

Le moteur sait exécuter des instructions ; le programme reçu précise le travail à effectuer. Un token est le résultat transporté vers Google. Il ne constitue pas, à lui seul, une autorisation d’accès.

  1. Recevoir

    Dans le parcours knitsail étudié, /sgasync transporte le script, son hash et le programme encodé.

  2. Décoder

    Le client transforme les octets, décode l’UTF-8 et lit l’enveloppe JSON. Cette étape est distincte du chiffrement des tokens.

  3. Exécuter

    La VM exécute le programme, lit des signaux et produit une sortie. Les rôles varient selon le programme.

  4. Transmettre

    La sortie emprunte le transport du parcours : cookie, en-tête de requête ou appel à un service.

SG_SS ≠ X-Sg-Ss

Le premier est un cookie de la page intermédiaire ; le second est un en-tête ajouté à une requête réessayée. Leurs noms proches ne les rendent pas interchangeables.

Hash ≠ verdict

Les hash SHA-256 correspondent aux scripts vérifiés. Ils identifient le code reçu ; ils ne mesurent pas la confiance accordée au navigateur.

Enveloppe /sgasync et champs envoyés à Validate

Le transport /sgasync

Le client lit la réponse comme un tableau d’octets, ajoute 97 à chaque octet modulo 256, puis décode le résultat en UTF-8 et le parse. Cette transformation de transport est distincte du chiffrement des tokens. Les réponses analysées ont une enveloppe de huit positions. Le programme reste un objet distinct du script de la VM.

Position (base 0)Contenu observé
0bfkj : marqueur d’enveloppe.
1Tableau de six positions ; le script JavaScript occupe la position 5, les cinq premières sont nulles.
2 et 6null dans les réponses étudiées.
3SHA-256 base64url du script.
4Programme encodé, avec préfixe de fonction d’entrée.
5knitsail : espace de noms.
7Chaîne auxiliaire. Sa signification n’est pas établie par cette analyse.

Les champs envoyés à Validate

Les requêtes Validate du corpus initial du 17 octobre sont toutes des GET : le paramètre reqpld contient un tableau JSON. Leur réponse est [""]. Le code relie ses positions aux numéros de champs du message. Nous n’attribuons aux valeurs que les significations démontrées.

Champ du messagePosition et contenu
1Position 0 : token texte. Corpus initial : 1 471 à 1 544 caractères (53 % des appels) ; pilote VPS : 1 417 à 1 441 (12 %) ; série contrôlée : 1 400 à 1 448 (35 %). Ces distributions ne prouvent ni acceptation ni invisibilité de l’instrumentation.
2Position 1 : contexte ; le champ imbriqué 9 contient un sous-message dont le champ 1 reçoit ei.
3Position 2 : nulle dans toutes les requêtes. Le code prévoit une représentation binaire alternative au token texte, dans le même groupe exclusif que le champ 1.
4Position 3 : valeur 3 dans toutes les requêtes. Le code prévoit aussi 1 et 2 pour une autre source de résultat ; cela ne démontre pas trois niveaux de confiance.
10

Ce que révèle l’intérieur du moteur

Un moteur obfusqué et renouvelé

Identifiants courts, chaînes reconstruites, dispatch par états : le code masque sa structure. Les hash, noms d’entrée et paramètres changent, même lorsque le numéro de version reste 41.

Des opérations de chiffrement

Les moteurs combinent additions, rotations et XOR (ARX). Les réglages diffèrent entre VM. Une ressemblance avec une famille de chiffrements ne suffit pas à identifier précisément l’algorithme.

Des outils pour résumer les mesures

Le code contient une mise à jour de moyenne et de dispersion de type Welford, ainsi qu’un réservoir de taille bornée. Ces capacités ne démontrent pas quelles métriques le serveur utilise pour décider.

Une sensibilité au texte du code

Dans les contrôles hors ligne, extraire le code avec son enveloppe d’origine rétablit les sorties. Reformater ensuite le code intérieur les modifie de nouveau.

Enveloppe conservée + intérieur extraitSorties rétablies
Même enveloppe + intérieur reformatéSorties différentes

Ce contraste est reproduit sur tous nos échantillons. Il soutient une sensibilité au texte source, sans localiser un mécanisme d’intégrité précis ni établir la détection des modifications côté serveur.

Chiffrement, statistiques et contrôles hors ligne

Chiffrement et rotation des scripts

Le code combine additions, rotations et XOR (ARX), avec des rotations de 8 et 3 bits. Les moteurs étudiés utilisent 14, 15 ou 16 tours. Une constante peut être littérale ou passée en argument : l’analyse suit les appels pour éviter de confondre une limite de boucle voisine avec le nombre de tours. Une ressemblance de structure avec une famille de chiffrements n’établit pas l’identité de l’algorithme.

Copie étudiéeToursConstante
Résultats, 17 octobre152905
Publicité, 17 octobre152905
knitsail, 17 octobre161088
Accueil, 18 octobre151795

Les réglages diffèrent donc aussi entre VM servies au même moment. Les changements de hash et de constante documentent une rotation des scripts ; ils ne prouvent ni l’invalidation immédiate des anciens tokens ni la durée d’acceptation côté serveur. Les caractères initiaux ! et * et la structure binaire des tokens servent à comparer des familles de tokens ; ils ne renseignent pas sur le verdict.

Statistiques et événements réellement observés

Le moteur contient une mise à jour incrémentale de moyenne et de dispersion de type Welford, puis calcule sqrt(M2 / n) : un écart-type de population. Il contient aussi un réservoir de taille bornée. Ces routines décrivent des capacités du moteur ; leur présence ne démontre pas les métriques ni les seuils que le serveur emploie pour décider.

n = n + 1
delta = x - mean
mean = mean + delta / n
M2 = M2 + delta * (x - mean)
standard_deviation = sqrt(M2 / n)

La VM des résultats installe quatre types de listener : mousedown, mouseup, touchstart, touchend. Knitsail ajoute notamment les mouvements de souris, le clavier et la molette. Aucun listener scroll n’a été observé dans ces sessions. Le code contient une liste de 101 noms de balises, ce qui ne prouve pas que 101 éléments soient systématiquement surveillés.

Knitsail et la VM YouTube lisent navigator.webdriver, testent l’attribut webdriver de la balise HTML et inspectent des propriétés de window.chrome. La VM des résultats et knitsail inventorient aussi les noms globaux de la page. Les noms recherchés dans cet inventaire ne sont pas établis. Aucun seuil chiffré séparant un humain d’un bot n’est démontré par ces observations.

Les 96 replays VM et les 48 cas synthétiques du contrôleur sont documentés dans le rapport expérimental. Les replays ne transmettent aucun token produit à Google. Les tests du contrôleur reproduisent des branches locales, sans mesurer la validité des tokens côté serveur.

11

Méthode, preuves et approfondissements

Les conclusions ci-dessus réunissent les observations par sujet. Les corpus restent distincts dans les sources pour conserver leur traçabilité.

Méthode et configurations testées

Configurations. Chrome 153.0.8010.52 (même binaire, SHA-256 identique), Playwright 1.51.0, Camoufox Firefox 135.0.1-beta.24 (paquet 0.4.11), client HTTP sans JavaScript. La matrice factorielle utilise Chrome avec interface, un viewport de 1280 × 720, une connexion CDP dans chaque cellule et un getter webdriver natif vérifié avant et après navigation. Les quatre combinaisons sont exécutées dans deux blocs randomisés, avec deux témoins ordinaires extérieurs. Les contrôles des réglages de Playwright comparent séparément le flag, la liste de 17 fonctions désactivées et les 29 autres options.

Terrain. Profils dédiés sans compte Google personnel, navigateur avec interface sous Xvfb. Pilote sur IP native du VPS et sorties VPN ; série de session sur une sortie américaine fixe, avec langue fr-FR, hl=fr et gl=fr. Le pays de sortie diffère donc du pays demandé, mais reste identique entre les branches comparées.

Corpus. Observation des VM : quatre sessions, trois profils et neuf pages de résultats. Pilote VPS : 37 essais enregistrés, dont trois arrêtés avant Google, plus une navigation en session ouverte. Contrôle NID : 21 navigations, dont trois profils sources et neuf paires. Comparaison des navigateurs et réglages : 37 navigations. Matrice factorielle webdriver : huit essais et deux témoins. Contrôle de fond : 444 captures récoltées, du 13 novembre 2025 au 17 octobre 2026 ; 441 exécutées hors ligne et 69 tracées pour les familles de tests, trois réponses Google Flights de format différent écartées. Stockage : six programmes décodés, 134 états recensés, une chaîne de 21 passages avec clics distincts sur le programme d’août. Autres contrôles hors ligne : 96 replays de quatre VM et 48 cas de contrôleur. Ces corpus ne s’additionnent pas en un taux de réussite.

Contrôles. La matrice webdriver conserve la requête, le binaire et les adresses IPv4 et IPv6 ; chaque navigation utilise un profil neuf. Le contrôle de session conserve la configuration et l’identité JavaScript observée, vérifie l’IP avant et après navigation et alterne l’ordre. Huit paires sur neuf ne diffèrent que par NID parmi les cookies transmis ; la dernière diffère aussi par __Secure-STRP. Les attentes sont mesurées depuis l’ouverture du contexte. Le stockage est étudié hors ligne avec le moteur et le programme récoltés, sans soumettre les tokens produits à Google.

Limites. Essais courts, états serveur non contrôlés, deux répétitions par cellule factorielle. Le signal est réglé par des commandes du navigateur dans un environnement où AutomationControlled est désactivé. Les profils neufs ne sont pas identiques bit à bit. Les replays ne testent pas l’acceptation des tokens en ligne ; la limite FIFO à vingt passages est établie sur le programme d’août. Le test de visibilité ne permet pas de comparer visible/caché. Les dates du contrôle de fond sont des dates de capture, encadrées par nos captures voisines ; le contexte des requêtes récoltées est inconnu. Cookies, tokens, HAR, profils et captures brutes restent privés.

Documents de l’étude et scripts de Google

Document de l’étude

Autres sources et études

Oct 2026 Google BotGuard : ce que nos tests révèlent sur l'accès aux résultats, le rôle de la session, les contrôles exécutés dans le navigateur (jusqu'à quatre VM sur une page de résultats) et la fiabilité des SERP Oct 2026 Comment Gemini cherche et choisit ses citations : 222 753 recherches Google analysées dans 76 450 conversations publiques Oct 2026 Search & fan-out capture V6 : notre extension Chrome capture aussi Gemini (fan-out, passages cités, classifieur de prompts) et les pubs ChatGPT Oct 2026 API de décision de Chrome testée : transformer ce que tapent les visiteurs en filtres, de 38 % à 85 % de bonnes réponses selon le moteur, et EmbeddingGemma 2 comparé Oct 2026 Google Lens Shopping : le classement des 752 catégories d'objets (ALLOWLIST, NEUTRAL, DENYLIST) et la liste appliquée en 2026 Sept 2026 Google Ads deep dive : comment Google Ads lit le site, relie les pages aux requêtes, génère les créations et prépare l'enchère Sept 2026 RESONEO Shop, une démo WebMCP : 135 outils exposés à un agent IA, 33 scénarios guidés, données en direct et simulées Août 2026 Ce que ChatGPT récupère, ce qu'il montre, ce qu'il cite (mis à jour : il cherche beaucoup moins large, et cite autant) Août 2026 Google Map disséqué : 72 signaux de ranking et l'architecture qui relie le Web, les lieux et l'IA Juil 2026 ChatGPT experiments tracker : ce qu'OpenAI teste avant de le déployer More stuffs...
RESONEO