Un site sait-il distinguer un agent IA d'une personne ?
10 stacks d'automatisation réellement lancés contre une page vivante — pas une liste de conseils.
Les agents IA commencent à naviguer, comparer et acheter sur vos pages. Que vous vouliez les accueillir ou les tenir à l'écart, la première question est la même : votre site peut-il seulement les voir ? Nous avons lancé de vrais navigateurs automatisés — headless simple, avec fenêtre, puis des patchs stealth de plus en plus aboutis — contre une page vivante, en notant pour chacun quels contrôles se sont déclenchés. Lisez l'échelle, pas la dernière case : chaque contrôle qu'un stack caché contourne coûte à son auteur un correctif de plus, à chaque session et sur chaque site.
Que récupèrent les agents IA sur vos pages ?
Analyse gratuite : ce que ChatGPT, Claude et Perplexity lisent sur votre site, et quoi corriger.
Les stacks, et ce qui les a trahis
Chaque ligne est un navigateur réellement lancé contre la page. Les étiquettes sont les contrôles déclenchés.
- Playwright, default headless (chromium headless shell)Détecté
5 contrôles dans la page · 2 contrôles sur les en-têtes
navigator.webdriver is true"Headless" in the User-Agent stringWebGL renderer is a software rasterizerZero browser plugins and MIME typesNo real interaction observed on the page"Headless" in the User-Agent headerNo Accept-Language header sent - Playwright, full Chromium in headless modeDétecté
4 contrôles dans la page · 1 contrôles sur les en-têtes
navigator.webdriver is true"Headless" in the User-Agent stringWebGL renderer is a software rasterizerNo real interaction observed on the page"Headless" in the User-Agent header - Playwright, headed Chromium on a virtual displayDétecté
2 contrôles dans la page · 0 contrôles sur les en-têtes
navigator.webdriver is trueWebGL renderer is a software rasterizer - Headless shell + the public stealth patch (spoofs webdriver, plugins, languages, cores, window size, permissions, WebGL vendor) and a real-browser User-AgentDétecté
6 contrôles dans la page · 2 contrôles sur les en-têtes
The webdriver flag has been rewrittennavigator.plugins is not a real PluginArrayNative browser functions have been replacedSpoofed properties answer to an object that is not a browserUser-Agent string disagrees with Client HintsNo real interaction observed on the pageNo Accept-Language header sentSec-CH-UA version disagrees with the User-Agent - Headless shell + a stealth patch written AGAINST these checks (flag moved to the prototype, real PluginArray of real Plugin objects, every patched function reporting itself as native, UA client hints aligned)Détecté
2 contrôles dans la page · 2 contrôles sur les en-têtes
Spoofed properties answer to an object that is not a browserNo real interaction observed on the pageNo Accept-Language header sentSec-CH-UA version disagrees with the User-Agent - Headless shell + the same counter-patch, plus a brand check inside every fake getter (it refuses an object that is not a browser, exactly as the engine does)Détecté
2 contrôles dans la page · 2 contrôles sur les en-têtes
The refusal itself is acted out by page codeNo real interaction observed on the pageNo Accept-Language header sentSec-CH-UA version disagrees with the User-Agent - Headless shell + the same brand-checked counter-patch, plus stack hiding (Error.captureStackTrace strips the patch’s own frames, so the acted refusal looks like the engine’s)Non détecté
1 contrôles dans la page · 2 contrôles sur les en-têtes
No real interaction observed on the pageNo Accept-Language header sentSec-CH-UA version disagrees with the User-Agent - Headless shell + the same stack-hiding counter-patch, but installed in the top frame only (a patch that does not think about frames)Détecté
2 contrôles dans la page · 2 contrôles sur les en-têtes
A fresh realm disagrees with this oneNo real interaction observed on the pageNo Accept-Language header sentSec-CH-UA version disagrees with the User-Agent - The best evasion measured here (stack-hiding counter-patch, installed in every frame — the only row that comes out clean), plus the driver moving the mouse across the page: the answer to "automation never touches anything"Non détecté
1 contrôles dans la page · 2 contrôles sur les en-têtes
Pointer moved in a perfectly even progressionNo Accept-Language header sentSec-CH-UA version disagrees with the User-Agent - Not a browser at all: a raw HTTP client (Node http.request) that copies every Chrome header value — User-Agent, Sec-CH-UA, Accept-Language, sec-fetch-* — but not the order a real Chromium network stack emits them inNon détecté
0 contrôles dans la page · 1 contrôles sur les en-têtes
Headers arrive in an order no Chromium emits
Quels contrôles sont rentables
Combien de stacks chaque contrôle attrape, comptés uniquement sur les lignes où il est jugeable.
| Contrôle | Couche | Stacks attrapés |
|---|---|---|
| No real interaction observed on the page | Dans la page | 7 sur 9 |
| No Accept-Language header sent | En-têtes HTTP | 7 sur 10 |
| Sec-CH-UA version disagrees with the User-Agent | En-têtes HTTP | 6 sur 10 |
| navigator.webdriver is true | Dans la page | 3 sur 9 |
| WebGL renderer is a software rasterizer | Dans la page | 3 sur 9 |
| Spoofed properties answer to an object that is not a browser | Dans la page | 2 sur 9 |
| "Headless" in the User-Agent string | Dans la page | 2 sur 9 |
| "Headless" in the User-Agent header | En-têtes HTTP | 2 sur 10 |
| Native browser functions have been replaced | Dans la page | 1 sur 9 |
| navigator.plugins is not a real PluginArray | Dans la page | 1 sur 8 |
| Zero browser plugins and MIME types | Dans la page | 1 sur 9 |
| Pointer moved in a perfectly even progression | Dans la page | 1 sur 1 |
| A fresh realm disagrees with this one | Dans la page | 1 sur 9 |
| The refusal itself is acted out by page code | Dans la page | 1 sur 8 |
| User-Agent string disagrees with Client Hints | Dans la page | 1 sur 9 |
| The webdriver flag has been rewritten | Dans la page | 1 sur 9 |
| Headers arrive in an order no Chromium emits | En-têtes HTTP | 1 sur 10 |
| Known Selenium / ChromeDriver / PhantomJS markers | Dans la page | 0 sur 9 |
| navigator.hardwareConcurrency is zero | Dans la page | 0 sur 9 |
| Empty navigator.languages | Dans la page | 0 sur 9 |
| Window outerWidth/outerHeight is zero | Dans la page | 0 sur 9 |
| Permissions API vs Notification.permission mismatch | Dans la page | 0 sur 9 |
| No sec-fetch-* headers sent | En-têtes HTTP | 0 sur 10 |
| Header User-Agent differs from the in-page one | En-têtes HTTP | 0 sur 10 |
Recensement en direct
112 sessions ont exécuté l'auto-test dans leur propre navigateur et renvoyé un verdict anonyme — jamais une empreinte. Part de ces sessions où chaque signal s'est déclenché :
| Contrôle | Part des sessions |
|---|---|
| Zero browser plugins and MIME types | 95% |
| "Headless" in the User-Agent string | 92% |
| navigator.webdriver is true | 90% |
| WebGL renderer is a software rasterizer | 90% |
| No real interaction observed on the page | 17% |
| Pointer moved in a perfectly even progression | 5% |
| User-Agent string disagrees with Client Hints | 2% |
| The webdriver flag has been rewritten | 1% |
| Native browser functions have been replaced | 1% |
Jusqu'ici la plupart des sessions viennent de notre propre banc et de robots, pas d'une audience tierce : à lire comme un catalogue de signaux, pas comme une mesure du web.
Navigateurs de la famille Chromium uniquement (ceux installés sur la machine qui mesure) et sans GPU, donc le contrôle du rendu logiciel se déclenche sur toutes les lignes — c'est là une propriété de la machine, pas de l'automatisation. Dernière mesure : 2026-09-20.