Wie Bot-Erkennung funktioniert – und warum Clearcote die Engine patcht
Der übliche Ansatz patcht navigator.webdriver, spooft den WebGL-Vendor und überschreibt navigator.plugins per Skript. Erkennungssysteme schlagen trotzdem an – und der Grund ist struktureller Natur, nicht eine weitere Eigenschaft, die übersehen wurde.
Ein JavaScript-Spoof verrät sich selbst
Ein JS-Spoof ist eine Funktion an einer Stelle, an die eine native gehört. Ein Erkennungsskript lässt den zurückgegebenen Wert beiseite und prüft, ob das, was ihn zurückgibt, nativ ist:
| Das Indiz | Warum es einen JS-Spoof entlarvt |
|---|---|
Selbstverrat über toString | Eine native Methode ergibt als String function get vendor() { [native code] }; ein Override liefert seinen eigenen Quelltext – ein einziges .toString() entlarvt ihn. |
Deskriptor / hasOwnProperty | getOwnPropertyDescriptor legt umdefinierte Properties offen, und hasOwnProperty('toString') liefert bei einer manipulierten Funktion true, wo eine native false liefert. |
TypeError bei falschem this | Native Getter werfen bei falschem Receiver einen ganz bestimmten TypeError; ein naiver Shim bleibt still – und genau diese Stille ist das Signal. |
| Frische Referenz aus einem anderen Realm | Ein Erkennungsskript holt sich ein unberührtes Function.prototype.toString aus einem frischen iframe oder Web Worker und wendet es auf Ihren Getter an – aus einem anderen Realm als dem Ihres Main-World-Patches. Heraus kommt Ihr Quelltext. Erwischt. |
Clearcote hat keine solche Schicht. Der Getter für navigator.userAgent ist der C++-Getter: Er meldet [native code], weil er nativer Code ist, identisch in jedem Realm – ob Main Frame, iframe oder Worker. Es gibt kein JavaScript-Hijacking, das sich erkennen ließe.
Die drei Ebenen der Bot-Erkennung
Moderne Anti-Bot-Systeme lesen drei strukturell verschiedene Oberflächen aus, an drei getrennten Stellen. Ein einzelnes Tool deckt selten alle drei ab:
| Ebene | Die Indizien | Wo die Lösung ansetzt | Clearcote |
|---|---|---|---|
| A · Treiber / Binary | cdc_-Variablen von ChromeDriver, die Oberfläche des WebDriver-Protokolls | Direkt über CDP steuern, chromedriver weglassen | ✅ ein schlichtes Chromium-Binary – keine Treiber-Artefakte |
| B · CDP-Nebeneffekte | Leaks durch Runtime.enable, injizierte Init-Skripte, Ausführung in der Main World, der Standard-Viewport von Automatisierungstools | Die Steuerungs- bzw. CDP-Client-Schicht | ✅ die Engine neutralisiert das Leak durch Runtime.enable, das SDK injiziert standardmäßig keine Skripte, und die Start-Defaults vermeiden den Standard-Viewport von Automatisierungstools (wo Ihr Client eigene Skripte ausführt, bleibt ihm überlassen) |
| C · Fingerprint-Oberfläche | Canvas, WebGL, Audio, Schriften, navigator, TLS – über Main Frame, iframes und Worker hinweg | Die Engine (C++), weil JS-Overrides sich selbst verraten | ✅ genau das ist Clearcote |
Worauf es am meisten ankommt: keine Naht zwischen Spoof und Realität
Weil die Steuerung in der Engine sitzt, stammen das JavaScript, das eine Seite sieht, und der Netzwerk-Handshake darunter aus ein und demselben echten Chromium. Es gibt keine Naht zwischen gespooftem JS und echtem TLS, die ein Abgleich aufdecken könnte – genau die Schwachstelle, an der injektionsbasierte Tools auffliegen. Ein --fingerprint-Seed erzeugt eine einzige, in sich konsistente Maschine über Canvas, WebGL, Audio, Schriften und Hardware hinweg. Der TLS- und HTTP/2-Handshake darunter stammt von der Engine selbst, und er passt, weil die Persona genau die Version meldet, die die Engine tatsächlich ist – lassen Sie brandVersion ungesetzt, damit das so bleibt.
Und wenn das Rauschen selbst das Indiz ist, schalten Sie es ab – Canvas und WebGL liefern dann ihre natürlichen Werte, während der Identitäts-Spoof aktiv bleibt (gerendertes Audio und Client-Rects werden ohnehin nie verrauscht, und die Skalare für Rate und Latenz des AudioContext folgen weiterhin der Persona; warum, steht hier):
await launch({ fingerprint: "u1", fingerprintNoise: false }); // identity on, per-site farbling offOhne Rauschen teilen sich Identitäten auf demselben Rechner einen Canvas-Hash. canvasNoise: false schaltet nur Canvas 2D ab und behält das WebGL-Rauschen bei (lizenzierter Build ab 150 r12+ und offener Build ab 150).
Kohärenz von Netzwerk und Locale
Die Persona ist nur die halbe Miete: Auch Zeitzone, Sprache und WebRTC-Adresse müssen zu dem Ort passen, von dem der Traffic kommt. Hinter einem Proxy starten Sie mit geoip – das SDK ermittelt die Exit-IP des Proxys, setzt Zeitzone, Sprachliste, Geolocation und WebRTC-Adresse für diese Region und bricht den Start ab, wenn es keine Region ermitteln kann. Ohne diese Option folgt die Zeitzone der Sprache (en-US bedeutet New York), egal in welchem Land der Proxy steht. Die Optionen finden Sie unter Playwright & Puppeteer.
Deshalb patcht Clearcote die C++-Engine, statt JavaScript zu injizieren. Was Sie steuern können, steht unter Fingerprint-Flags; wie die Engine alle Signale gemeinsam kohärent hält, unter Architektur.
38.921 Zeilen zwischen Standard-Chromium und Clearcote Pro.
So weit ist der Pro-Build von dem Chromium entfernt, das Google ausliefert. Jeder Wert, den eine Website lesen kann, wird dort gesetzt, wo Chromium ihn berechnet. So beschreiben die Seite, ihre Worker und ihre iframes alle dasselbe Gerät.
- Canvas
- WebGL
- WebGPU
- Audio
- Schriften
- Bildschirm und Fenster
- WebRTC
- TLS
- Client Hints
- Eingabe-Timing
- Stimmen und Codecs
Pro-Build, gezählt am Patch-Stack von r57 (Chromium 156.0.8078.47). Der kostenlose offene Build ist ein kleinerer, öffentlicher Patch-Satz.
345 files changed, 35915 insertions(+), 3006 deletions(-)
240 Patches
Geänderte Dateien nach Bereich
- Rendering-Engine (Blink)118
- Browser (chrome/)52
- Content-Schicht42
- Komponenten39
- Netzwerk-Stack22
- UI und Fenster14
- TLS (BoringSSL)11
- V8 und URL17
- Alles andere30
Weiterlesen