Introduzione
Quando automatizzi un browser con Playwright, Puppeteer o Selenium, il browser espone segnali che lo identificano come controllato a livello di programmazione. La proprietà navigator.webdriver è impostata su true. Gli oggetti specifici del framework vengono visualizzati nell'ambiente JavaScript. I protocolli di console e debug lasciano artefatti. La modalità headless si comporta diversamente dalla modalità headed in modi sottili.
Questi segnali esistono perché i framework di automazione necessitano di hook nel browser per funzionare. Il problema è che questi stessi hook sono osservabili da qualsiasi JavaScript in esecuzione sulla pagina.
I segnali osservabili
navigator.webdriver
La specifica W3C WebDriver ha introdotto navigator.webdriver. Quando un browser è controllato tramite il protocollo WebDriver, questa proprietà restituisce true. È stato progettato come meccanismo di trasparenza, ma è ora il segnale di automazione più comunemente controllato.
In Chromium standard, questo valore è impostato a livello C++ durante l'inizializzazione del browser quando è presente il flag --enable-automation, che Playwright e Puppeteer aggiungono per impostazione predefinita.
Punti di iniezione del framework
Ogni framework di automazione inietta codice in punti specifici:
- Playwright inietta funzioni di binding (
__playwright__binding__) e script di inizializzazione in ogni nuovo contesto di pagina - Puppeteer inietta helper di script di valutazione e codice di gestione della sessione CDP
- Selenium utilizza il protocollo WebDriver che imposta flag di automazione a livello di browser
Artefatti CDP
Chrome DevTools Protocol consente ai tool esterni di controllare il browser. Quando una sessione CDP è attiva, diversi segnali diventano osservabili:
Runtime.enableeConsole.enablemodificano il comportamento diconsole.loge dei trace dello stack di errori- Le connessioni della sessione CDP vengono visualizzate su endpoint WebSocket specifici
- Determinati comportamenti del browser cambiano quando i domini CDP sono attivi
Differenze della modalità headless
La modalità headless di Chromium standard differisce dalla modalità headed in diversi modi. L'array navigator.plugins potrebbe essere vuoto. WebGL potrebbe eseguire il fallback al rendering software. Le dimensioni della finestra potrebbero avere valori insoliti.
Limiti dei Stealth Plugins
Gli stealth plugin tentano di pulire dopo che il framework ha già impostato i valori di automazione. Eseguono l'override di navigator.webdriver con un getter JavaScript, eliminano oggetti del framework dall'ambito globale e patching di altre proprietà rivelatrici.
Questo approccio ha una debolezza fondamentale: la pulizia avviene in JavaScript, dopo l'inizializzazione del contesto della pagina. I valori originali esistono brevemente prima di essere sovrascritti e il codice di pulizia stesso è osservabile.
I siti possono:
- Controllare le modifiche al descrittore della proprietà su
navigator.webdriver - Osservare che
Object.getOwnPropertyDescriptorrestituisce un getter invece di un valore - Notare differenze di tempistica tra lo stato iniziale e lo stato con patch
- Cercare i modelli di codice del plug-in stealth stesso
Come BotCloud affronta questo
BotCloud rimuove gli artefatti del framework di automazione a livello di motore, prima dell'esecuzione di qualsiasi codice di pagina:
navigator.webdriverrestituiscefalsenativamente, non attraverso un override JavaScript- Nessun oggetto di binding del framework è presente nei contesti di pagina
- L'attività della sessione CDP è isolata da JavaScript della pagina
- Le modalità headless e headed producono comportamento osservabile identico
Poiché questi cambiamenti avvengono nel motore del browser stesso, non c'è patch JavaScript da ispezionare, nessun gap temporale da sfruttare e nessuna anomalia del descrittore della proprietà da trovare.
Implicazioni pratiche
Con BotCloud, puoi usare l'intera superficie API di Playwright o Puppeteer senza alcun stealth plugin o soluzione alternativa di configurazione. I tuoi script di automazione rimangono puliti e focalizzati sulla logica di business piuttosto sul patching delle impronte.
// No stealth plugin needed - just connect and automate
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://cloud.bots.win?token=YOUR_TOKEN',
});
const page = await browser.newPage();
await page.goto('https://example.com');
// navigator.webdriver is false, no automation traces leaked