Browser-Plugin: Menschliches Verhalten simulieren (Verhaltens-Bot-Schutz) #202

Closed
opened 2026-10-22 12:03:48 +00:00 by alf · 1 comment
Owner

iris-browser 0.5.0 — menschlicher Benutzer simulieren

Motivation

Folge auf #123 (Build des Browser-Plugins, abgeschlossen). Statisches Stealth sitzt
bereits (patchright 1.61.0: navigator.webdriver, Headless-Chrome-UA, Plugins, window.chrome).

Nachweis aus dem Chat vom 2026-10-22 („Öffne den Webbrowser und suche auf ebay.de …“,
Export auf dem Desktop, Chat 786261CC): Die Akamai-splashui-Challenge wird im
Plugin-Chromium bestanden, Startseite und /itm/ liefern 200 — aber die Trefferliste
/sch/i.html liefert hart 403 (Referenznummer wechselt pro Request). Ursache:
Akamai-Bot-Manager bewertet pro Endpoint unterschiedliche Vertrauenslevel. Das
Challenge-Basislevel reicht für Startseite/Einzelangebote, nicht für die am stärksten
geschützte Suchseite. Die Lücke ist die Verhaltens-Schicht: CDP-gesteuertes
Headless-Chromium erzeugt sprungartige Mauspositionen, Mousedown/Up im Millisekunden-Takt,
fill() in einem Event und Einzel-Wheel-Events — ohne die Telemetrie, die Akamais
Sensor-Skript von einer menschlichen Session erwartet (Mausbewegung, Tipp-Rhythmus,
Scrollmuster, Dwell).

Anwendungsfälle

  • Portale mit Login und Session (z. B. Rechnungen abholen) — Login macht der Nutzer selbst
    im Seitenpanel (bestehende Skill-Regel), danach agiert der Agent in der Session.
  • eBay.de-Preisrecherche/-verfolgung (ad hoc im Chat; periodisch max. ~1×/Woche).
  • Foren-Threads verfolgen und promptgesteuert nach Markdown weitergeben (laufend).

Nicht im Scope: Checkout-/Kauf-Automatisierung, Account-Flows.

Design-Entscheidungen (geklart am 2026-10-22)

Thema Entscheidung
Simulationsschicht nur Verhalten, nicht statisch (steht schon) und nicht IP-/Langzeit-Pattern
Cursor-Verhalten dezent: saubere Bézier-Kurven, kleiner Tremor, moderate Pausen — muss im Seitenpanel nicht bug-artig wirken
Anwendung immer an (Standard), zentral in commands.mjs; betrifft auch --click-at (Panel-Klicks des Nutzers)
Kill-Switch --fast on / --fast off pro Chat, persistiert im Chat-Zustand (store.mjs), gilt für alle Folgebefehle; Fast ≈ heutiges Timing (Zielmitte, ohne Kurvenflug)
Parameter ein Modul lib/human.mjs, benannte Konstanten mit Verteilungsfunktion (rand aus crypto.random, nie deterministisch); kein Config-File/Settings-UI in v1
SKILL.md zwei Zeilen: --fast-Switch für offensichtlich ungeschützte Sites bei ausgiebigen Aufgaben; geschützte Sites: Startseite → Formular (nicht Direkt-URL), bei Wiederholung Suchbegriff variieren

Simulierte Signale (v1)

  • Klick: Bézier-Mausflug 100–400 ms, Hover 50–400 ms, Drückphase 60–160 ms, Klick leicht versetzt zur Elementmitte
  • fill/type: char-für-char 30–120 ms/Zeichen mit Wortpausen; Bestandsinhalt per Ctrl+A, nicht fill()-Clear
  • scroll: Delta in 100–150 px-Notschritte zerlegt, 60–200 ms Takt, Bursts mit Pausen
  • Dwell nach Seitenload: 1–4 s „Lesen“ mit gelegentlichem 1–5 px-Maus-Tremor
  • Zwischen-Befehl-Timing: LLM-Denkzeit ist bereits unregelmäßig, nichts zu tun

Explizit nicht in v1

  • permanentes Hintergrund-Maus-Tremor (nur während Dwell)
  • Profil-Warmup-Automatisierung (das geteilte Profil kumuliert Historie ohnehin)
  • Headed-Modus, Per-Site-Profile, Config-Layer

Abnahme (drei Stufen)

  1. Harter Canary: eBay-Flow Startseite → Dwell → Suchbegriff tippen → Finden klicken → finale URL /sch/, HTTP 200, DOM ≥ 5 Item-Karten. Als --canary-Opt-in in tests/smoke.sh (nicht automatisch — externe Abhängigkeit, kann sich ändern). Vorher/Nachher reproduzierbar auf derselben IP.
  2. Manuell (Nutzer): Rechnungs-Portal-Flow — Login im Panel, Agent liest danach Seiten in der Session ohne Flagging.
  3. Regression: Foren-Tracking läuft weiter; Agent-Tasks auf ungeschützten Sites bleiben praktikabel (--fast); Panel wirkt dezent, nicht bug-artig.

Risiko

CDP-Input erzeugt isTrusted=true-Events, die echten Maus-/Tastaturevents prinzipiell
ähnlich sind — aber Akamai kann die Lücke über Nicht-JS-Schichten schließen (CDP-Protokoll-
Spuren, Headless-Traces, die patchright 1.61 nicht deckt). Dann schlägt der Canary auch
nach dem Release fehl. In dem Fall ist das Feature nicht defekt: Der Befund (welche
Schicht detektiert) gehört in das Issue, es bleibt offen, nächste Schicht folgt. Dokumentierter
Alltags-Fallback für geschützte Daten: web_search (Suchmaschinen-Index statt Live-Scrape),
wie bereits im Chat vom 22.10. genutzt.

Umsetzung

  1. lib/human.mjs: Verteilungsfunktionen + humanMove, humanClick(loc|x,y), humanType, humanScroll, dwell (Parameter als benannte Konstanten)
  2. commands.mjs: click/fill/type/scroll/click-at über human.mjs routen, --fast-Switch lesen/ persistieren
  3. store.mjs: fast im Chat-Zustand
  4. SKILL.md: --fast-Zeile + Navigation-Regeln für geschützte Sites
  5. tests/smoke.sh: --canary (eBay) + Timing-Sanity-Test (human > 50 ms, fast < 20 ms)
  6. PLAN.md: neue Etappe + Lessons Learned; Changelog; Version 0.5.0 in plugin.json

Release

Registry-Veröffentlichung erst nach ausdrücklicher Freigabe und grüner Canary
(Updates erreichen die Nutzer sofort).

Referenzen

  • Chat-Export 2026-10-22_Öffne-den-Webbrowser-und-suche-auf-ebayd.irischat.irischat (Desktop), Chat 786261CC-9F3B-41C4-A3AE-1A608FF3A5C4
  • #123 (Plugin-Build, abgeschlossen)
# iris-browser 0.5.0 — menschlicher Benutzer simulieren ## Motivation Folge auf #123 (Build des Browser-Plugins, abgeschlossen). Statisches Stealth sitzt bereits (patchright 1.61.0: `navigator.webdriver`, Headless-Chrome-UA, Plugins, `window.chrome`). Nachweis aus dem Chat vom **2026-10-22** („Öffne den Webbrowser und suche auf ebay.de …“, Export auf dem Desktop, Chat `786261CC`): Die Akamai-`splashui`-Challenge wird im Plugin-Chromium bestanden, Startseite und `/itm/` liefern 200 — aber die Trefferliste `/sch/i.html` liefert **hart 403** (Referenznummer wechselt pro Request). Ursache: Akamai-Bot-Manager bewertet pro Endpoint unterschiedliche Vertrauenslevel. Das Challenge-Basislevel reicht für Startseite/Einzelangebote, nicht für die am stärksten geschützte Suchseite. Die Lücke ist die **Verhaltens-Schicht**: CDP-gesteuertes Headless-Chromium erzeugt sprungartige Mauspositionen, Mousedown/Up im Millisekunden-Takt, `fill()` in einem Event und Einzel-Wheel-Events — ohne die Telemetrie, die Akamais Sensor-Skript von einer menschlichen Session erwartet (Mausbewegung, Tipp-Rhythmus, Scrollmuster, Dwell). ## Anwendungsfälle - Portale mit Login und Session (z. B. Rechnungen abholen) — Login macht der Nutzer selbst im Seitenpanel (bestehende Skill-Regel), danach agiert der Agent in der Session. - eBay.de-Preisrecherche/-verfolgung (ad hoc im Chat; periodisch max. ~1×/Woche). - Foren-Threads verfolgen und promptgesteuert nach Markdown weitergeben (laufend). **Nicht** im Scope: Checkout-/Kauf-Automatisierung, Account-Flows. ## Design-Entscheidungen (geklart am 2026-10-22) | Thema | Entscheidung | |---|---| | Simulationsschicht | nur Verhalten, nicht statisch (steht schon) und nicht IP-/Langzeit-Pattern | | Cursor-Verhalten | dezent: saubere Bézier-Kurven, kleiner Tremor, moderate Pausen — muss im Seitenpanel nicht bug-artig wirken | | Anwendung | immer an (Standard), zentral in `commands.mjs`; betrifft auch `--click-at` (Panel-Klicks des Nutzers) | | Kill-Switch | `--fast on` / `--fast off` pro Chat, persistiert im Chat-Zustand (`store.mjs`), gilt für alle Folgebefehle; Fast ≈ heutiges Timing (Zielmitte, ohne Kurvenflug) | | Parameter | ein Modul `lib/human.mjs`, benannte Konstanten mit Verteilungsfunktion (`rand` aus `crypto.random`, nie deterministisch); **kein** Config-File/Settings-UI in v1 | | SKILL.md | zwei Zeilen: `--fast`-Switch für offensichtlich ungeschützte Sites bei ausgiebigen Aufgaben; geschützte Sites: Startseite → Formular (nicht Direkt-URL), bei Wiederholung Suchbegriff variieren | ### Simulierte Signale (v1) - Klick: Bézier-Mausflug 100–400 ms, Hover 50–400 ms, Drückphase 60–160 ms, Klick leicht versetzt zur Elementmitte - `fill`/`type`: char-für-char 30–120 ms/Zeichen mit Wortpausen; Bestandsinhalt per Ctrl+A, nicht `fill()`-Clear - `scroll`: Delta in 100–150 px-Notschritte zerlegt, 60–200 ms Takt, Bursts mit Pausen - Dwell nach Seitenload: 1–4 s „Lesen“ mit gelegentlichem 1–5 px-Maus-Tremor - Zwischen-Befehl-Timing: LLM-Denkzeit ist bereits unregelmäßig, nichts zu tun ### Explizit nicht in v1 - permanentes Hintergrund-Maus-Tremor (nur während Dwell) - Profil-Warmup-Automatisierung (das geteilte Profil kumuliert Historie ohnehin) - Headed-Modus, Per-Site-Profile, Config-Layer ## Abnahme (drei Stufen) 1. **Harter Canary:** eBay-Flow `Startseite → Dwell → Suchbegriff tippen → Finden klicken` → finale URL `/sch/`, HTTP 200, DOM ≥ 5 Item-Karten. Als `--canary`-Opt-in in `tests/smoke.sh` (nicht automatisch — externe Abhängigkeit, kann sich ändern). Vorher/Nachher reproduzierbar auf derselben IP. 2. **Manuell (Nutzer):** Rechnungs-Portal-Flow — Login im Panel, Agent liest danach Seiten in der Session ohne Flagging. 3. **Regression:** Foren-Tracking läuft weiter; Agent-Tasks auf ungeschützten Sites bleiben praktikabel (`--fast`); Panel wirkt dezent, nicht bug-artig. ## Risiko CDP-Input erzeugt `isTrusted=true`-Events, die echten Maus-/Tastaturevents prinzipiell ähnlich sind — aber Akamai kann die Lücke über Nicht-JS-Schichten schließen (CDP-Protokoll- Spuren, Headless-Traces, die patchright 1.61 nicht deckt). Dann schlägt der Canary auch nach dem Release fehl. In dem Fall ist das Feature nicht defekt: Der Befund (welche Schicht detektiert) gehört in das Issue, es bleibt offen, nächste Schicht folgt. Dokumentierter Alltags-Fallback für geschützte Daten: `web_search` (Suchmaschinen-Index statt Live-Scrape), wie bereits im Chat vom 22.10. genutzt. ## Umsetzung 1. `lib/human.mjs`: Verteilungsfunktionen + `humanMove`, `humanClick(loc|x,y)`, `humanType`, `humanScroll`, `dwell` (Parameter als benannte Konstanten) 2. `commands.mjs`: click/fill/type/scroll/click-at über `human.mjs` routen, `--fast`-Switch lesen/ persistieren 3. `store.mjs`: `fast` im Chat-Zustand 4. `SKILL.md`: `--fast`-Zeile + Navigation-Regeln für geschützte Sites 5. `tests/smoke.sh`: `--canary` (eBay) + Timing-Sanity-Test (human > 50 ms, fast < 20 ms) 6. `PLAN.md`: neue Etappe + Lessons Learned; Changelog; Version 0.5.0 in `plugin.json` ## Release Registry-Veröffentlichung erst nach ausdrücklicher Freigabe **und** grüner Canary (Updates erreichen die Nutzer sofort). ## Referenzen - Chat-Export `2026-10-22_Öffne-den-Webbrowser-und-suche-auf-ebayd.irischat.irischat` (Desktop), Chat `786261CC-9F3B-41C4-A3AE-1A608FF3A5C4` - #123 (Plugin-Build, abgeschlossen)
Author
Owner

PR #209 gemergt: feat(browser): Menschliches Benutzerverhalten: Rhythmus, Lese-Pausen, --fast, --eval in Hauptwelt; 0.5.0 (#202)
#209

Commits:

  • feat(browser): Menschliches Benutzerverhalten: Rhythmus, Lese-Pausen, --fast, --eval in Hauptwelt; 0.5.0 (#202)

Stand (0.5.0)

Befund: Ausgelöst durch den Chat vom 22.10.: Das Plugin-Chromium besteht die statischen
Schichten (Akamai-Challenge, Startseite, /itm/), aber die Trefferliste /sch/i.html lieferte
hart 403 — die offene Schicht war die Verhaltens-Telemetrie (Maus, Tipp-Rhythmus, Scroll, Dwell).

Geändert:

  • lib/human.mjs (neu): Rhythmus-Mensch — Bézier-Mausflug (500–1400 px/s, ease in/out, ±1,5 px
    Tremor), Hover 60–420 ms, Drückphase 50–160 ms, Klick versetzt zur Elementmitte, fill mit
    Fokus-Klick + Strg/Cmd-A + char-für-char (30–120 ms, Wortpausen, gelegentliche Zögerung),
    Scroll in 100–150 px-Notschritten in Bursts, Dwell 1,2–4,2 s nach echten Seiten
    (Loopback/about: ohne Pause), Mausposition je Seite gemerkt. Entropie aus crypto.
  • lib/commands.mjs: alle Aktionen (click, click-at, fill, type, key, scroll) über human.mjs;
    --fast on/off je Chat (persistiert in state.json, in der Ausgabe als fast an sichtbar);
    Dwell nach Navigation und zurück/vorwärts.
  • --eval läuft mit isolatedContext: false in der Hauptwelt der Seite — patchright 1.61
    evaluate sonst standardmäßig in einer isolierten Welt (Fork-Änderung gegen playwright-core
    1.61.0), dort sind Fenster-Globalen unsichtbar; mit false gelten wieder die
    Playwright-Standard-Semantik.
  • tests/smoke.sh: Tempo-Check über eine Testseite, die Mausereignisse loggt (Mensch ≥ 5
    Bewegungen, Drückphase ≥ 50 ms; Fast ≤ 2, < 20 ms) + --canary gegen ebay.de (Opt-in).
  • Doku: SKILL.md (--fast-Zeile, Regeln für geschützte Sites), system_prompt.md, plugin.json
    0.5.0 + Changelog, store/changelog.md, PLAN.md (Entscheidungen, Canary-Befund, Lessons Learned).

Geprüft (gemessen, lokal, temporäres IRIS_APP_SUPPORT):

  • Smoke-Test komplett grün (alle 0.4.x-Checks + beide Tempo-Checks), bash tests/smoke.sh.
  • Mausflug: Easeing-Bug gefangen und repariert (Formel t = steps² schickte den Klick Tausende
    Pixel aus dem Viewport; danach landet der Klick im Element, Fokus + Eingabe verifiziert).
  • --eval-Welt: rohes CDP + Instrumentierung des patchright-Bundles belegt die Weltzuordnung
    (Hauptwelt name=""/isDefault, patchright-Isolate name="utility");
    page.evaluate(…, null, false) liest die Hauptwelt (Probe: Inline-Skript-Variable sichtbar).
  • --fast on/off pro Chat: persistiert und in der Ausgabe sichtbar; Tempo-Unterschied gemessen.
  • Syntax- und Laufzeit-Check commands.mjs (TDZ-Fehler bei fast gefangen und repariert).

Nicht geprüft:

  • Canary gegen ebay.de: nicht grün. Frisches Profil vom Heim-IP: Homepage hart 403
    („Error Page | eBay") — Edge-Block auf IP-Reputation, vor der Verhaltens-Schicht.
    Die Suchseiten-Prüfung (/sch/ 200, ≥ 5 Treffer) ist damit heute nicht erreichbar;
    der Canary meldet diesen Fall eigenständig. Reputations-Blockade kann sich mit Tagen
    auflösen; ein warmes Profil (Session-Cookies) verhält sich evtl. anders.
  • Portal-Login-Flow (Stufe 2) und Foren-Regression (Stufe 3) — vom Nutzer im Alltag.

Grenzen: CDP-Input erzeugt isTrusted-Events, die echten Eingaben prinzipiel ähnlich sind,
aber Akamai kann die Lücke über Nicht-JS-Schichten schließen (CDP-Traces, Headless-Fingerabdrücke
unterhalb der JS-Ebene). Ob die Verhaltens-Schicht ausreicht, entscheidet der Canary/Alltag.

Offen: Canary erneut nach IP-Reputations-Ruhe oder von anderer IP; Registry-Publikation
0.5.0 erst nach ausdrücklicher Freigabe.

PR #209 gemergt: feat(browser): Menschliches Benutzerverhalten: Rhythmus, Lese-Pausen, --fast, --eval in Hauptwelt; 0.5.0 (#202) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/209 Commits: - feat(browser): Menschliches Benutzerverhalten: Rhythmus, Lese-Pausen, --fast, --eval in Hauptwelt; 0.5.0 (#202) --- ## Stand (0.5.0) **Befund:** Ausgelöst durch den Chat vom 22.10.: Das Plugin-Chromium besteht die statischen Schichten (Akamai-Challenge, Startseite, `/itm/`), aber die Trefferliste `/sch/i.html` lieferte hart 403 — die offene Schicht war die Verhaltens-Telemetrie (Maus, Tipp-Rhythmus, Scroll, Dwell). **Geändert:** - `lib/human.mjs` (neu): Rhythmus-Mensch — Bézier-Mausflug (500–1400 px/s, ease in/out, ±1,5 px Tremor), Hover 60–420 ms, Drückphase 50–160 ms, Klick versetzt zur Elementmitte, `fill` mit Fokus-Klick + Strg/Cmd-A + char-für-char (30–120 ms, Wortpausen, gelegentliche Zögerung), Scroll in 100–150 px-Notschritten in Bursts, Dwell 1,2–4,2 s nach echten Seiten (Loopback/`about:` ohne Pause), Mausposition je Seite gemerkt. Entropie aus `crypto`. - `lib/commands.mjs`: alle Aktionen (click, click-at, fill, type, key, scroll) über `human.mjs`; `--fast on/off` je Chat (persistiert in `state.json`, in der Ausgabe als `fast an` sichtbar); Dwell nach Navigation und zurück/vorwärts. - `--eval` läuft mit `isolatedContext: false` in der **Hauptwelt** der Seite — patchright 1.61 evaluate sonst standardmäßig in einer isolierten Welt (Fork-Änderung gegen playwright-core 1.61.0), dort sind Fenster-Globalen unsichtbar; mit `false` gelten wieder die Playwright-Standard-Semantik. - `tests/smoke.sh`: Tempo-Check über eine Testseite, die Mausereignisse loggt (Mensch ≥ 5 Bewegungen, Drückphase ≥ 50 ms; Fast ≤ 2, < 20 ms) + `--canary` gegen ebay.de (Opt-in). - Doku: SKILL.md (`--fast`-Zeile, Regeln für geschützte Sites), system_prompt.md, plugin.json 0.5.0 + Changelog, store/changelog.md, PLAN.md (Entscheidungen, Canary-Befund, Lessons Learned). **Geprüft (gemessen, lokal, temporäres `IRIS_APP_SUPPORT`):** - Smoke-Test komplett grün (alle 0.4.x-Checks + beide Tempo-Checks), `bash tests/smoke.sh`. - Mausflug: Easeing-Bug gefangen und repariert (Formel `t = steps²` schickte den Klick Tausende Pixel aus dem Viewport; danach landet der Klick im Element, Fokus + Eingabe verifiziert). - `--eval`-Welt: rohes CDP + Instrumentierung des patchright-Bundles belegt die Weltzuordnung (Hauptwelt `name=""`/`isDefault`, patchright-Isolate `name="utility"`); `page.evaluate(…, null, false)` liest die Hauptwelt (Probe: Inline-Skript-Variable sichtbar). - `--fast on/off` pro Chat: persistiert und in der Ausgabe sichtbar; Tempo-Unterschied gemessen. - Syntax- und Laufzeit-Check `commands.mjs` (TDZ-Fehler bei `fast` gefangen und repariert). **Nicht geprüft:** - **Canary gegen ebay.de: nicht grün.** Frisches Profil vom Heim-IP: Homepage hart 403 („Error Page | eBay") — Edge-Block auf IP-Reputation, **vor** der Verhaltens-Schicht. Die Suchseiten-Prüfung (`/sch/` 200, ≥ 5 Treffer) ist damit heute nicht erreichbar; der Canary meldet diesen Fall eigenständig. Reputations-Blockade kann sich mit Tagen auflösen; ein warmes Profil (Session-Cookies) verhält sich evtl. anders. - Portal-Login-Flow (Stufe 2) und Foren-Regression (Stufe 3) — vom Nutzer im Alltag. **Grenzen:** CDP-Input erzeugt `isTrusted`-Events, die echten Eingaben prinzipiel ähnlich sind, aber Akamai kann die Lücke über Nicht-JS-Schichten schließen (CDP-Traces, Headless-Fingerabdrücke unterhalb der JS-Ebene). Ob die Verhaltens-Schicht ausreicht, entscheidet der Canary/Alltag. **Offen:** Canary erneut nach IP-Reputations-Ruhe oder von anderer IP; Registry-Publikation 0.5.0 erst nach ausdrücklicher Freigabe.
alf closed this issue 2026-10-24 21:19:48 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
iris/iris-plugins#202
No description provided.