{
  "name": "CreaCaptcha",
  "display_name": "CreaCaptcha",
  "slug": "creationell-captcha",
  "version": "1.0.1",
  "download_url": "https://github.com/creationell-dev/creationell-captcha/releases/download/v1.0.1/creationell-captcha.zip",
  "checksum_sha256": "f7aaaadb327330eedc9225895175e1bb3cd7200d1aab86f4d7f817380aba961a",
  "requires": "6.9",
  "tested": "7.0",
  "requires_php": "8.3",
  "author": "creationell® – die Werbeagentur <marketing@creationell.de>",
  "author_profile": "https://www.creationell.de/",
  "contributors": {
    "creationell-dev": {
      "display_name": "creationell-dev",
      "profile": "https://profiles.wordpress.org/creationell-dev",
      "avatar": "https://wordpress.org/grav-redirect.php?user=creationell-dev&s=36"
    },
    "JPKCom": {
      "display_name": "JPKCom",
      "profile": "https://profiles.wordpress.org/JPKCom",
      "avatar": "https://wordpress.org/grav-redirect.php?user=JPKCom&s=36"
    }
  },
  "tags": [
    "captcha",
    "spam",
    "anti-spam",
    "anti-bot",
    "proof of work"
  ],
  "license": "GPL-2.0-or-later",
  "license_uri": "https://www.gnu.org/licenses/gpl-2.0.html",
  "text_domain": "creationell-captcha",
  "domain_path": "/languages",
  "network": false,
  "requires_plugins": [],
  "homepage": "https://github.com/creationell-dev/creationell-captcha",
  "last_updated": "2026-06-02",
  "sections": {
    "description": "<p><strong>CreaCaptcha</strong> ist ein vollständig selbst-gehostetes\nSchutz-Plugin für WordPress. Es kombiniert einen Proof-of-Work-Captcha\nauf Basis der MIT-Bibliothek <code>altcha-org/altcha</code> mit einer\nFirewall, einem per-IP-Rate-Limiter, einem Under-Attack-Modus,\nE-Mail-Obfuskation und einer optionalen Bild-Code-Challenge. Es gibt\nkeine externen API-Aufrufe, kein Lizenz-Gate, keine SaaS-Anbindung und\nkeine Telemetrie — alle Funktionen laufen lokal in WordPress.</p>\n<p>Das Plugin schützt die vier WordPress-Kernformulare (Kommentare,\nLogin, Registrierung, Passwort-Reset) sowie automatisch alle Formulare\ngängiger Form-Plugins (<strong>Contact Form 7</strong>,\n<strong>Forminator</strong>, <strong>WPForms</strong>,\n<strong>WooCommerce</strong> mit Checkout / My-Account-Login /\nRegistrierung / Lost-Password). Eigene oder fremde Formulare lassen sich\nüber den Shortcode <code>[creationell_captcha]</code>, das Template-Tag\n<code>creationell_captcha_widget()</code> oder den generischen\nInterceptor (Pfad-Schutz) absichern.</p>\n<h3 id=\"key-features\">Key Features</h3>\n<ul>\n<li><strong>Proof-of-Work-Captcha</strong> — Server stellt eine\nChallenge aus, Browser löst sie mit PBKDF2/SHA-256 oder Argon2id; kein\nKlick-Puzzle, keine Bilderkennung, keine Tracking-Cookies</li>\n<li><strong>Vollständig selbst-gehostet</strong> — Keine externen\nDienste, kein API-Key, kein Lizenz-Server. Datenfluss bleibt zu 100 %\nauf dem WordPress-Host</li>\n<li><strong>Schutz der WordPress-Kernformulare</strong> — Kommentare,\nLogin, Registrierung und Passwort-Reset einzeln zuschaltbar</li>\n<li><strong>Vier Form-Plugin-Integrationen</strong> — Contact Form 7,\nForminator, WPForms, WooCommerce (Checkout + My-Account-Login +\nRegistrierung + Lost-Password) mit Auto-Inject und\nServer-Verifikation</li>\n<li><strong>Generischer Interceptor</strong> — Eigene Form-Pfade per\nURL-Muster (mit <code>*</code>-Wildcards und <code>!</code>-Ausschluss)\nschützen, fail-closed</li>\n<li><strong>Action-Schutz</strong> — <code>admin-post.php</code> /\n<code>admin-ajax.php</code>-Aktionen über die <code>action</code>-Liste\nabsichern, mit <code>*</code>-Wildcards und\n<code>!</code>-Ausschluss</li>\n<li><strong>Inject-Pfade</strong> — Auf konfigurierten Pfaden wird die\nSicherheitsabfrage automatisch in jedes <code>&lt;/form&gt;</code>\ninjiziert (idempotent — bereits geschützte Formulare werden\nübersprungen)</li>\n<li><strong>Shortcode &amp; Template-Tag</strong> —\n<code>[creationell_captcha]</code> oder\n<code>creationell_captcha_widget()</code> für freihändigen Einbau in\nbeliebige Formulare; CF7-Form-Tag mit identischem Namen</li>\n<li><strong>Bild-Code-Challenge</strong> — Optionale zweite Stufe nach\nPoW: serverseitig gerendertes PNG (PHP-GD, mitgelieferte DejaVu-TTF),\n4–8-stelliger Code mit Anti-OCR-Verzerrung; Trigger wahlweise Immer,\nUnder-Attack, Rate-Limit-Schwelle oder Watch-Liste (OR-verknüpft)</li>\n<li><strong>Under-Attack-Modus</strong> — HTTP-503-Interstitial mit\ninvisiblem PoW-Widget für anonyme Besucher; HMAC-signiertes Pass-Cookie\nfür die konfigurierte Dauer</li>\n<li><strong>Firewall</strong> — IP-Blocklist &amp; -Allowlist (exakt +\nCIDR, v4 &amp; v6), User-Agent-Blocklist (Wildcard), Proxy-Modus mit\nkonfigurierbarem Forwarded-Header</li>\n<li><strong>Vertrauenswürdige Proxies</strong> — Eigene IP-/CIDR-Liste,\nCloudflare-IP-Auto-Refresh aus den offiziellen Listen, optionaler Trust\nvon Private-Netzen; nur dann wird <code>X-Forwarded-For</code>\nausgewertet</li>\n<li><strong>Rate-Limit</strong> — Per-IP Fixed-Window-Counter mit drei\nScopes (Core-Formulare / alle Formulare / global); konfigurierbarer\nMax-Wert, Fenster und Retry-After</li>\n<li><strong>Drei Bypass-Mechaniken</strong> — IP-Allowlist (CIDR),\nUser-Agent-Wildcard-Liste und Cookie-Bypass (<code>name=wert</code>);\nTreffer umgehen Firewall, Rate-Limit, Captcha und Under-Attack</li>\n<li><strong>Analytics &amp; Event-Log</strong> — Aggregierte Tages- und\nStundenzähler je Ereignistyp (<code>verified</code> /\n<code>failed</code> / <code>firewall</code> / <code>ratelimit</code> /\n<code>underattack</code> / <code>challenge</code>); optional\ndetaillierte Event-Tabelle mit IP, Pfad, Plugin, Aktion, Form-ID, Grund,\nUser-Agent, Referrer, User-ID und Request-Body-Fingerprint</li>\n<li><strong>DSGVO-konforme IP-Anonymisierung</strong> — Standard: IPv4\nauf das letzte Oktett, IPv6 auf die letzten 80 Bit trunkiert</li>\n<li><strong>Statistik-Dashboard</strong> — Drei Tabs (Übersicht /\nVerlauf / Ereignisse), vier Zeitfenster (24 h / 7 Tage / 30 Tage / 90\nTage), Filterleiste, seitenweises Blättern und CSV-Export</li>\n<li><strong>E-Mail-Obfuskation</strong> — Verschleiert\n<code>mailto:</code>-Links und Klartextadressen per XOR-Hex; zwei Modi\n(Content-Filter oder Ganzseiten-Buffer für theme-hartkodierte\nAdressen)</li>\n<li><strong>Widget-Customization</strong> — Anzeigemodus (Standard /\nschwebend / Overlay / Bar / Invisible), Interaktionstyp, Auto-Trigger,\nTheme, Branding-Toggle, Akzentfarbe, eigenes CSS und Strings-Override\nfür alle Übersetzungstexte</li>\n<li><strong>Backend-UI mit sechs Tabs</strong> — Captcha, Formulare,\nFirewall, Under-Attack, <strong>Analytics</strong>, E-Mail-Schutz —\nalles unter einem gemeinsamen „Änderungen speichern”</li>\n<li><strong>Werkzeuge-Seite</strong> — Export / Import der Einstellungen\nals JSON, vollständiger Werksreset und ein gesonderter „Standardwerte\nladen”-Schritt (Listen bleiben erhalten)</li>\n<li><strong>WP-CLI-Integration</strong> — Befehlsgruppe\n<code>wp creacaptcha</code> für Status, Diagnose, Modul-Aktivierung,\nListen, Event-Log, Cloudflare-Refresh und Bypass-Tests</li>\n<li><strong>Self-Hosted-Updater</strong> — Updates direkt aus\nGitHub-Releases mit SHA-256-Manifest-Verifikation (timing-safe\n<code>hash_equals</code>)</li>\n<li><strong>Kein Lizenz-Gate</strong> — Alle Funktionen sind dauerhaft\naktiv. GPL-2.0-or-later</li>\n</ul>\n<hr />\n",
    "installation": "<ol type=\"1\">\n<li>Den Plugin-Ordner <code>creationell-captcha</code> nach\n<code>/wp-content/plugins/</code> hochladen — entweder als ZIP über\n<strong>Plugins → Installieren → Plugin hochladen</strong> oder per\nFTP/SSH/<code>wp plugin install</code>.</li>\n<li>Unter <strong>Plugins → Installierte Plugins</strong> das Plugin\n<strong>CreaCaptcha</strong> aktivieren.</li>\n<li>Den neuen Menüpunkt <strong>CreaCaptcha</strong> im\nWordPress-Adminbereich öffnen.</li>\n<li>Unter <strong>CreaCaptcha → Einstellungen</strong> im Tab\n<strong>Captcha</strong> den Master-Toggle prüfen (Standard: aktiv) und\nden Tab <strong>Formulare</strong> durchgehen, um\nWordPress-Kernformulare und Form-Plugins zu aktivieren.</li>\n<li>Falls eigene Formular-Pfade abgesichert werden sollen: im Tab\n<strong>Captcha → Interceptor</strong> die Liste <strong>Geschützte\nPfade</strong> pflegen.</li>\n<li>Empfohlen: einmal <strong>CreaCaptcha → Statistik</strong> öffnen,\ndamit der Event-Log aktiviert werden kann (optional — die\nAggregat-Statistik läuft auch ohne).</li>\n</ol>\n<h3 id=\"anforderungen\">Anforderungen</h3>\n<ul>\n<li>WordPress <strong>6.9</strong> oder höher</li>\n<li>PHP <strong>8.3</strong> oder höher</li>\n<li>Für die Bild-Code-Challenge: PHP-Erweiterung\n<strong>GD</strong></li>\n<li>Für den optionalen Argon2id-Algorithmus: PHP-Erweiterung\n<strong>Sodium</strong></li>\n</ul>\n<p>Das Plugin prüft die Mindestversionen beim Aktivieren und zeigt im\nAdmin-Bereich eine deutliche Hinweisleiste, wenn die Umgebung zu alt\nist.</p>\n<h3 id=\"updates\">Updates</h3>\n<p>Updates kommen direkt aus dem GitHub-Repo. Der eingebaute\nSelf-Hosted-Updater (<code>includes/class-plugin-updater.php</code>)\nprüft regelmäßig das Manifest, vergleicht Versionen und installiert das\noffiziell signierte ZIP samt SHA-256-Checksum.</p>\n<hr />\n",
    "changelog": "<h3 id=\"section\">1.0.1</h3>\n<ul>\n<li>Fix: Contributor-Einträge im Plugin-Detail-Popup erhalten jetzt\neinen <code>display_name</code> — zuvor loggte WordPress-Core eine\nPHP-Warning und zeigte die Contributor-Namen nicht an. Das\nUpdate-Manifest liefert das Feld nun mit; der Updater ergänzt es als\nFallback auch für ältere Manifeste.</li>\n<li>Fix: Der <code>no_update</code>-Eintrag des Updaters enthält jetzt\n<code>new_version</code>, <code>package</code>, <code>tested</code> und\n<code>requires_php</code> — zuvor loggte WP-CLI bei\n<code>wp plugin list</code> eine PHP-Warning, wenn das Plugin aktuell\nwar.</li>\n<li>Entfernt: Der seit v0.19.0 veraltete WP-CLI-Alias\n<code>wp creacaptcha refresh-cloudflare-ips</code>. Bitte\n<code>wp creacaptcha cloudflare refresh</code> verwenden.</li>\n<li>Verbessert: Die Plugin-Banner werden jetzt verlustfrei als AVIF\nkodiert.</li>\n</ul>\n<h3 id=\"section-1\">1.0.0</h3>\n<p>Erstes stabiles Release. CreaCaptcha ist ein vollständig\nselbst-gehosteter Spamschutz für WordPress — ohne externe Dienste, ohne\nTracking, ohne Lizenz-Gate.</p>\n<p>Funktionsumfang:</p>\n<ul>\n<li>Proof-of-Work-Captcha (ALTCHA-kompatibel, PBKDF2/Argon2id) für\nKommentare, Login, Registrierung und Passwort-Reset</li>\n<li>Formular-Integrationen: Contact Form 7, Forminator, WPForms,\nWooCommerce (Checkout, Login, Registrierung, Lost-Password)</li>\n<li>Generischer Interceptor für beliebige URL-Pfade und\nWordPress-Actions</li>\n<li>Firewall (IP-/CIDR-/User-Agent-Listen), per-IP-Rate-Limiter,\nProxy-Support inkl. Cloudflare</li>\n<li>Under-Attack-Modus mit anpassbarer 503-Interstitial-Seite (Texte,\nFarben, Logo, Custom-CSS)</li>\n<li>Bild-Code-Challenge als optionale zweite Captcha-Stufe</li>\n<li>E-Mail-Obfuskation (Content-Filter oder Ganzseiten-Buffer)</li>\n<li>Statistik-Dashboard, Event-Log mit Suche/Filter/CSV-Export</li>\n<li>Umfassende WP-CLI-Integration (<code>wp creacaptcha …</code>)</li>\n<li>Widget-Anpassung (Themes, Farben, Custom-CSS, 20 Sprachen)</li>\n</ul>\n<p>Neu in diesem Release:</p>\n<ul>\n<li>Plugin-Banner für den WordPress-Update-Screen</li>\n<li>Dokumentations-Sektion in der README (Web-Doku, Update-Manifest,\nAPI-Referenz)</li>\n<li>Contributors-Angabe im Update-Manifest erweitert</li>\n</ul>\n<p>Das Update von v0.30.x erfolgt ohne Datenbank-Migration und ohne\nBreaking Changes — bestehende Einstellungen, Listen und Statistiken\nbleiben unverändert erhalten.</p>\n<h3 id=\"section-2\">0.30.1</h3>\n<p>Wartungsrelease: Release-Infrastruktur umgestellt — keine\nfunktionalen Änderungen am Plugin.</p>\n<ul>\n<li>Die Plugin-Releases werden ab dieser Version aus dem dedizierten,\nöffentlichen Release-Repository\n<code>github.com/creationell-dev/creationell-captcha</code>\nveröffentlicht. Download-, Update- und Dokumentations-URLs bleiben\nunverändert.</li>\n<li>Build-Pipeline gehärtet: GitHub-Actions und phpDocumentor auf feste\nVersionen gepinnt, Build-Staging vom Paketinhalt ausgeschlossen.</li>\n</ul>\n<h3 id=\"section-3\">0.30.0</h3>\n<p>Under-Attack Pass-Event &amp; Statistik-Übersicht — das Backend\nunterscheidet jetzt, ob ein Besucher die Under-Attack-Prüfung bestanden\nhat oder hängen blieb, und die Statistik-Übersicht erklärt ihre Zahlen\nselbst.</p>\n<ul>\n<li>Neuer Event-Typ <code>underattack_passed</code>: feuert, wenn ein\nBesucher die Under-Attack-PoW-Prüfung löst und das Pass-Cookie\nausgestellt wird. Erscheint in Übersicht, Verlauf, Ereignis-Filter,\nCSV-Export und WP-CLI (<code>wp creacaptcha stats</code>,\n<code>log list --type=underattack_passed</code>).</li>\n<li>Neues Log-Gate „Bestandene Under-Attack-Prüfungen loggen” (Default:\nan); Aggregat-Zähler laufen unabhängig davon.</li>\n<li>Statistik-Übersicht: vier KPI-Kacheln statt drei — „Abgewehrt (24\nh)” zählt nur noch echte Blocks (Firewall + Rate-Limit), Under-Attack\nhat eine eigene Kachel „Abfragen / bestanden”.</li>\n<li>Statistik-Übersicht: die flache Ereignis-Tabelle ist in vier\nthematische Gruppen mit Erklärungstext gegliedert (Formular-Captchas /\nAbgewehrte Zugriffe / Under-Attack-Modus / Technisch); nicht zugeordnete\nTypen landen automatisch in einer Auffanggruppe „Weitere\nEreignisse”.</li>\n<li>Keine DB-Migration nötig; bestehende Events und Zähler bleiben\nunverändert gültig.</li>\n</ul>\n<h3 id=\"section-4\">0.29.0</h3>\n<p>Logo im Under-Attack-Interstitial — die 503-Seite kann jetzt ein Logo\noberhalb der Überschrift anzeigen.</p>\n<ul>\n<li>Neues optionales Feld „Logo-URL” in der Under-Attack-Section\n„Erscheinungsbild”. Leer = kein Logo (Default); bestehende Sites sehen\nohne Aktion keine Änderung.</li>\n<li><code>UnderAttack::serve_interstitial()</code> reicht die URL als\n<code>$logo_url</code> ans Template; das Template rendert ein\nzentriertes <code>&lt;img class=\"crea-ua-logo\"&gt;</code> vor dem\n<code>&lt;h1&gt;</code>, gedeckelt auf <code>max-height: 128px</code>.\nAlt-Text = Website-Name (<code>get_bloginfo('name')</code>).</li>\n<li>Sanitization via <code>esc_url_raw()</code> beim Speichern\nentschärft gefährliche Schemata (<code>javascript:</code> o. Ä.);\nAusgabe zusätzlich mit <code>esc_url()</code>.</li>\n<li>Größe per <code>.crea-ua-logo</code> über das vorhandene „Eigenes\nCSS”-Feld überschreibbar. Setzbar über\n<code>wp creacaptcha settings set   underattack_logo_url &lt;url&gt;</code>.</li>\n</ul>\n<h3 id=\"section-5\">0.28.0</h3>\n<p>Feature-Modul 21 — Under-Attack-Customization: Wording und\nErscheinungsbild der Interstitial-Seite sind ab sofort über das Backend\nkonfigurierbar, ohne Plugin-Code zu patchen.</p>\n<ul>\n<li>Neue Section „Erscheinungsbild” im Under-Attack-Tab mit sieben\noptionalen Feldern: vier Texte (Browser-Tab-Titel, Überschrift,\nHinweistext, NoScript-Hinweis), zwei Farben (Hintergrund, Textfarbe) und\nein freies Custom-CSS-Feld.</li>\n<li>Renderer in <code>UnderAttack::serve_interstitial()</code> baut die\ndrei Variablen <code>$texts</code> / <code>$colors</code> /\n<code>$user_css</code> und reicht sie ans Template weiter; leere Felder\nfallen auf die existierenden Hartcode-Defaults zurück.</li>\n<li>Template (<code>includes/under-attack-interstitial.php</code>) nutzt\nzwei neue CSS-Variablen <code>--creationell-captcha-ua-bg</code> und\n<code>--creationell-captcha-ua-text</code> für die Farben. Ein zweiter\n<code>&lt;style&gt;</code>-Block direkt nach dem Default-Stylesheet\nnimmt das Custom-CSS auf — alle Regeln des Defaults sind dort\nüberschreibbar.</li>\n<li>Sanitization analog zu <code>widget_custom_css</code>:\n<code>wp_strip_all_tags()</code> neutralisiert\n<code>&lt;/style&gt;&lt;script&gt;</code>-Injection bevor der Wert die\nTemplate-Ausgabe erreicht.</li>\n<li>Alle sieben Felder sind über das bestehende\n<code>wp creacaptcha settings set &lt;key&gt; &lt;value&gt;</code>-CLI\nsetzbar — neue Field-Typen waren nicht nötig, alle Typen\n(<code>text</code>, <code>color</code>, <code>textblock</code>) gibt es\nseit Modul 14.</li>\n</ul>\n<p>Sites nach Update sehen ohne Aktion <strong>keine</strong> visuelle\nVeränderung — alle sieben Felder sind initial leer und das Template\nfällt damit auf die bisherigen Default-Werte zurück.</p>\n<h3 id=\"section-6\">0.27.2</h3>\n<p>Metadaten-Anpassung an WordPress 7.0 / 6.9.</p>\n<ul>\n<li><strong>Plugin-Header &amp; README:</strong>\n<code>Requires at least</code> von 6.8 auf 6.9 angehoben,\n<code>Tested up to</code> von 6.8 auf 7.0 nachgezogen. WordPress 7.0 ist\nseit kurzem produktiv; der Plugin-Test-Lauf der bisherigen Module 1–20\nist gegen 7.0 sauber.</li>\n<li><strong>Konstante:</strong> <code>CREATIONELL_CAPTCHA_MIN_WP</code>\nvon <code>'6.8'</code> auf <code>'6.9'</code> angehoben. Sites auf\nWordPress 6.8 oder älter erhalten beim Aktivieren jetzt die bestehende\nHinweisleiste „Erfordert WordPress 6.9 oder neuer.” statt das Plugin zu\nladen.</li>\n<li>Inline-Kommentar im Plugin-Bootstrap (<code>WordPress 6.8+</code> →\n<code>WordPress 6.9+</code>) und die interne Entwickler-Dokumentation\nkonsistent nachgezogen.</li>\n</ul>\n<p>Keine funktionalen Code-Änderungen.</p>\n<h3 id=\"section-7\">0.27.1</h3>\n<p>CSS-Fix: Widget-Abstand zum darauffolgenden Element im\nStandard-Modus.</p>\n<ul>\n<li><code>assets/css/widget.css</code>: Die Block-Flow-Abstandsregel auf\n<code>&lt;altcha-widget&gt;</code> ist von <code>margin-block-end</code>\nauf <code>padding-block-end</code> umgestellt und auf den\n<code>display=\"standard\"</code>-Modus eingeschränkt. Hintergrund: das\nWidget ist auf den geschützten Formularen typischerweise das letzte Kind\nim <code>&lt;form&gt;</code> — der bisherige\n<code>margin-block-end</code> kollabierte deshalb mit der Bottom-Kante\ndes Form-Elements (kein\n<code>padding-bottom</code>/<code>border-bottom</code>/eigene BFC),\nsodass visuell überhaupt kein Abstand zum nachfolgenden Inhalt blieb.\nPadding kollabiert nicht — der konfigurierbare Abstand (Default jetzt\n<code>1rem</code> statt <code>1.5em</code>) ist daher zuverlässig\nsichtbar. Der CSS-Variablenname\n(<code>--creationell-captcha-widget-margin-block-end</code>) bleibt aus\nKompatibilitätsgründen gleich.</li>\n<li>Floating/Overlay/Bar/Invisible-Modi bekommen den Abstand nicht mehr\nspurious mitgegeben — ihre eigentliche Widget-Darstellung ist\nposition-fixed bzw. display:none, ein Inline-Spacer wäre dort nur ein\ntoter 1.5em-Gap.</li>\n</ul>\n<h3 id=\"section-8\">0.27.0</h3>\n<p>Feature-Modul 20 — Widget-i18n: Die Sicherheitsabfrage erscheint\nendlich in der korrekten Sprache, ohne dass der Admin etwas\nkonfigurieren muss.</p>\n<ul>\n<li>Neue 20 vendorierte ALTCHA-Locale-Dateien unter\n<code>assets/js/altcha-i18n/</code> (DE, EN, FR-FR/CA, ES-ES/419, IT,\nNL, PT-PT/BR, PL, CS, SK, DA, SV, FI, NB, HU, RO, EL) — je ~3 KB,\nPage-Load lädt weiterhin nur eine Datei.</li>\n<li>Neuer Helper\n<code>creationell_captcha_resolve_widget_locale()</code> mit\nLookup-Tabelle (48 WP-Locale-Strings, inkl. formal/informal- Varianten)\nauf 20 ALTCHA-Codes.</li>\n<li><code>creationell_captcha_build_widget_markup()</code> enqueued die\npassende Locale-Datei lazy (analog zum Theme-CSS-Pattern) und setzt\n<code>language=\"&lt;code&gt;\"</code> am\n<code>&lt;altcha-widget&gt;</code>. Locales ohne Mapping überspringen\nbeide Schritte — das Widget nutzt dann seine eigene\n<code>&lt;html lang&gt;</code>/Browser-Detection.</li>\n<li>Zwei neue Filter <code>creationell_captcha_widget_locale_map</code>\nund <code>creationell_captcha_widget_locale</code> für Projekt-Overrides\nohne Plugin-Patch.</li>\n<li><code>wp creacaptcha status</code> zeigt eine neue Zeile\n„Widget-Sprache” mit dem effektiven ALTCHA-Code plus dem\nWP-Locale-Ursprung.</li>\n<li><code>widget_strings_override</code> bleibt unverändert und greift\nweiterhin als Pro-Schlüssel-Override <strong>on top</strong> der\nAuto-Locale.</li>\n</ul>\n<h3 id=\"section-9\">0.26.2</h3>\n<p>Bugfix-Release: schließt eine Verify-Regression aus v0.22.0 / Commit\n<code>c322b96</code>, die seit der Korrektur des\n<code>configuration</code>-JSON-Attributs das ALTCHA-Widget dazu\nbrachte, bei jedem gelösten PoW die <code>/code-verify</code>-Route\naufzurufen — und dort mit 400 <code>invalid_request</code> abgewiesen zu\nwerden, weil im Plain-Mode (ohne Code-Challenge im\n<code>/challenge</code>-Response) das <code>code</code>-Feld im Body\nfehlt.</p>\n<ul>\n<li><code>includes/widget.php</code>: <code>verifyUrl</code> wird im\n<code>configuration</code>-JSON nur noch dann emittiert, wenn das\nMaster-Setting <code>code_challenge_enabled</code> aktiv ist. Im\nStandardfall (Code-Challenge aus) verifiziert das Widget wieder rein\nclient-seitig, ohne den überflüssigen Server-Roundtrip.</li>\n<li><code>includes/code-challenge.php</code>: <code>/code-verify</code>\nakzeptiert das <code>code</code>-Feld jetzt als optional. Plain-Mode\n(<code>{ payload }</code> ohne <code>code</code>) durchläuft\n<code>Engine::verify_structural()</code>, prüft die Original-Signatur\nüber den gleichen Single-Use-Transient-Schlüssel wie\n<code>Engine::verify()</code> (verhindert, dass eine einzelne gelöste\nPoW in N frische Payloads multipliziert wird) und gibt eine frische\nsignierte Payload zurück. Code-Challenge-Modus bleibt funktional\nunverändert.</li>\n</ul>\n<p>Die ALTCHA-<code>verifyUrl</code>-Mechanik schaltet das Widget\npauschal in den Server-Verify-Modus — auch ohne Code-Challenge im\nResponse. Beide Fixes zusammen: saubere Standard-Konfiguration ohne\nRoundtrip <em>und</em> Defense-in-Depth, falls\n<code>code_challenge_enabled</code> aktiv ist aber kein Trigger\ngreift.</p>\n<h3 id=\"section-10\">0.26.1</h3>\n<p>UX-Polish-Release: schließt die drei nicht-essenziellen UX-Befunde\naus dem Qualitäts-Audit (Modul 18) ab.</p>\n<ul>\n<li>Neue <code>requires_select</code>-Semantik im Settings-Schema:\nFelder können jetzt nicht nur an einen booleschen Vorbedingungs-Toggle\ngekoppelt werden (<code>requires =&gt; 'foo_enabled'</code>), sondern\nauch an einen konkreten Wert eines anderen Select-Feldes\n(<code>requires_select =&gt; ['widget_display' =&gt;   'floating']</code>).\nRender-Layer setzt <code>disabled</code>, Sanitizer-Cascade bewahrt den\ngespeicherten Wert. Anwendung: die drei Floating-Felder\n<code>widget_floating_anchor</code>/<code>widget_floating_placement</code>/\n<code>widget_floating_offset</code> werden jetzt nur aktiv geschaltet,\nwenn der Widget-Anzeige-Modus auf „Schwebend” steht — in jedem anderen\nModus bleiben sie ausgegraut.</li>\n<li>Tools-Page „Auf Werkseinstellungen zurücksetzen”: deutliche\n<code>notice-warning</code>-Box oberhalb der Karte mit Hinweis auf die\nListen-Leerung und Verweis auf die ungefährliche „Standardwerte\nladen”-Karte.</li>\n<li>Wortwahl „Sicherheitsabfrage” (user-facing Help-Texte) vs. „Captcha”\n(technische/Admin-Kontexte wie Tab-Label, Section-Titel, Engine-\nBegriffe) bleibt bestehen — das Audit hat die aktuelle Trennung als\nakzeptabel eingestuft.</li>\n</ul>\n<h3 id=\"section-11\">0.26.0</h3>\n<p>Performance-Release: drei aufgeschobene Optimierungen aus dem\nQualitäts-Audit (Modul 18) — Settings-Memoize, Analytics-Bump-Memoize\nund ein Composite-Index auf der Events-Tabelle.</p>\n<ul>\n<li><code>creationell_captcha_get_settings()</code> cacht das Ergebnis\npro Request in einer statischen Variable. Bisher rief jede\nModul-Komponente (Interceptor, Firewall, Rate-Limiter, Under-Attack,\njede Form- Integration) die Funktion mehrfach pro Request, jedes Mal mit\n<code>array_merge</code> über ~70 Default-Keys. Invalidierung läuft über\ndie\n<code>update_option</code>/<code>add_option</code>/<code>delete_option</code>-Hooks\nfür <code>creationell_captcha_settings</code>, sodass Caller direkt nach\neinem Speichervorgang den frischen Wert sehen.</li>\n<li><code>Analytics::record()</code> sammelt die Daily- und\nHourly-Counter-Deltas in request-lokalen Static-Caches und flusht sie\nvia <code>add_action('shutdown', …)</code> in genau einem\n<code>get_option</code>/<code>update_option</code>-Paar pro\nCounter-Tabelle. Vorher: zwei Roundtrips pro Event — eine\n<code>/challenge</code>-Route mit aktivem\n<code>log_challenge</code>-Toggle und nachgelagerter Verifikation kommt\ndamit bei 4–6 Roundtrips an. Jetzt: maximal 2 Roundtrips, unabhängig von\nder Anzahl der Events. Die Cutoff-Pruning-Logik wandert in\n<code>apply_deltas()</code> und läuft jetzt einmal je Counter statt\neinmal je Event. Konkurrente Updates aus parallelen Requests bleiben\nerhalten (Flush liest frischen Stand und addiert nur die eigenen\nDeltas).</li>\n<li>Composite-Index\n<code>event_type_created (event_type, created_at)</code> auf der\nEvents-Tabelle. Dashboard-Queries mit <code>event_type</code>-Filter\n(Statistik-Tab, CSV-Export, Detail-Modal-Source) erzwangen bisher einen\nFilesort über den per-day-gesliceten Range. Mit dem Composite-Index\nläuft die typgefilterte Range-Abfrage als reiner Index-Range-Scan.\nMigration via <code>Analytics::ensure_table()</code> — dbDelta für\nFrischinstalls, <code>SHOW INDEX</code>-Guard plus\n<code>ALTER TABLE</code> als Fallback für bestehende Tabellen (dbDelta\nist für Index-Adds historisch unzuverlässig).\n<code>%i</code>-Identifier-Platzhalter konsistent mit\n<code>clear_events()</code>.</li>\n</ul>\n<h3 id=\"section-12\">0.25.0</h3>\n<p>Qualitäts-Audit-Release: Security-Härtung des Updaters,\nEvent-Log-Privacy, Body-Fingerprint-Maskierung sowie umfassende\nUX-Hilfetexte und Konsistenz- Fixes im Backend.</p>\n<p><strong>Sicherheit:</strong> - Updater\n(<code>includes/class-plugin-updater.php</code>): Checksum-Vergleich\nnutzt jetzt <code>hash_equals()</code> (timing-safe). Slug-Heuristik in\n<code>verify_download_checksum()</code> durch Exakt-Match gegen\n<code>manifest.download_url</code> ergänzt — verhindert Bypass über ein\nmanipuliertes Manifest mit Slug-freier Download-URL. Manifest-Fetch über\n<code>wp_safe_remote_get()</code> (Defense-in-Depth gegen SSRF). -\nEvent-Log: <code>Analytics::current_path()</code> reduziert\n<code>REQUEST_URI</code> auf den Pfad-Anteil. GET-Token,\nMagic-Login-Links und API-Keys landen damit nicht mehr im persistenten\nEvent-Log. - Request-Body-Fingerprint: Feldnamen mit sensitiven\nSubstrings (<code>password</code>, <code>secret</code>,\n<code>token</code>, <code>iban</code>, <code>api_key</code>,\n<code>cvv</code>, …) werden vor dem JSON-Encode durch\n<code>[masked:&lt;sha256-8&gt;]</code> ersetzt, um Custom-Form- Schemata\nnicht im Event-Log preiszugeben. Neuer Filter\n<code>creationell_captcha_request_body_sensitive_patterns</code> für\nprojektspezifische Erweiterungen. -\n<code>Analytics::clear_events()</code> nutzt jetzt\n<code>wpdb::prepare( 'DELETE FROM %i',   $table )</code> statt\nRoh-Interpolation (WP-6.2+-konform).</p>\n<p><strong>Backend-UX:</strong> - DSGVO-First: Default\n<code>analytics_anonymize_ip</code> von <code>false</code> auf\n<code>true</code>. Neue Installs anonymisieren IPs out-of-the-box;\nbestehende Installs behalten ihre Wahl. - Rate-Limit-Default\n<code>ratelimit_max</code> von 10 auf 30 (besser für Login-Scope — ein\nNutzer mit Tippfehler-Marathon läuft nicht mehr ins 5-Minuten-Lockout).\n- Tab-Reihenfolge: „Analytics” steht nun vor „E-Mail-Schutz” (näher an\nden Schutzmodulen). - Firewall-Tab: Sektionen sortiert auf Proxy →\nFirewall → Bypass → Rate-Limit (Bypass folgt der Firewall, deren Regeln\nsie überstimmt). - <code>widget_code_challenge_display</code> in die\nCode-Challenge-Section verschoben und an\n<code>code_challenge_enabled</code> gekoppelt. - 21 fehlende oder\nschwache Settings-Hilfetexte ergänzt (<code>algorithm</code>,\n<code>difficulty</code>, <code>challenge_expiry</code>, alle\n<code>widget_*</code>-Customization-Felder, Core-Forms-Toggles, alle\nForm-Plugin-Toggles, Rate-Limit-Felder,\n<code>firewall_proxy_header</code>,\n<code>firewall_ip_block</code>/<code>ua_block</code>,\n<code>underattack_enabled</code>, <code>analytics_event_log</code>,\n<code>bypass_cookies</code>,\n<code>firewall_cloudflare_auto_refresh</code>,\n<code>interceptor_skip_logged_in</code>). Section-Renderer für Engine,\nCode-Challenge und Firewall mit erklärenden Texten ergänzt (PoW-Konzept,\nOR-Logik der Trigger, CIDR-Notation). -\n<code>interceptor_actions</code>-Hilfetext nennt jetzt die\n<code>edit_posts</code>-Exemption (Autoren/Editoren weiterhin\nausgenommen). - Tools-Page: Reset-Karte + Confirm-Dialog erwähnen jetzt\nexplizit auch Interceptor- und Bypass-Listen.</p>\n<p><strong>WP-CLI:</strong> - <code>wp creacaptcha status</code> zeigt\ndrei neue Zeilen: Proxy-Modus, CF-Trust / CF-Auto-Refresh und\nIP-Anonymisierung. - <code>wp creacaptcha doctor</code> prüft\n<code>ext-sodium</code>, wenn der Algorithmus auf Argon2id steht — Error\nmit Fix-Vorschlag, wenn die Extension fehlt.</p>\n<p><strong>Code-Qualität:</strong> -\n<code>defined( constant_name: 'ABSPATH' )</code> →\n<code>defined( 'ABSPATH' )</code> in 48 Dateien. Named-Args auf\nPHP-Builtins sind nicht stabilitäts-garantiert und werden von\nStatic-Analyzern als Anti-Pattern geflaggt. - PHPDoc: über 20 eigene\n<code>do_action</code>/<code>apply_filters</code>-Hooks vollständig\ndokumentiert (<code>creationell_captcha_event</code>,\nInterceptor-Filter-Familie, WPForms-/WC-Autoinject-Filter),\nRepeat-Dispatches mit WordPress-Core- style „This action is documented\nin …“-Verweisen. - REST-Callback-PHPDocs in\n<code>includes/rest.php</code> und\n<code>includes/code-challenge.php</code> ergänzt\n(<code>@param</code>/<code>@return</code> mit Status-Code-Tabelle).</p>\n<p><strong>Tooling &amp; Doku:</strong> - <code>phpdoc.xml</code>\nVersion-Drift <code>0.1.0</code> → <code>0.25.0</code>. -\nPlugin-Header-Description nennt jetzt Firewall, Rate-Limit,\nUnder-Attack, E-Mail-Obfuskation und Code-Challenge (vorher: nur\nPoW-Spamschutz). - README-Description um WPForms-,\nWooCommerce-Integrationen und Code-Challenge-Absatz erweitert. -\n<code>uninstall.php</code>: Transient-Cleanup vom\n<code>_used_</code>-Prefix auf das gesamte\n<code>creationell_captcha_</code>-Prefix erweitert; entfernt jetzt auch\n<code>_cc_*</code>, <code>_rl_*</code> und\n<code>_git_update_*</code>-Caches/Locks.</p>\n<p><strong>Behebt:</strong> - Inkorrekt formulierter\nIPv6-Anonymisierungs-Hilfetext (<code>includes/settings.php</code>):\nstimmt jetzt mit der Code-Logik überein (erste 48 Bit bleiben, letzte 80\nBit auf 0). - Tippfehler „mehrmietigen” → „mehrmandantigen (Shared\nHosting)“. - <code>Tested up to: 6.9</code> → <code>6.8</code>\n(WordPress 6.9 ist Stand 2026-05-28 noch nicht released).</p>\n<h3 id=\"section-13\">0.24.0</h3>\n<ul>\n<li>WP-CLI-Nachzug Phase 2: schließt sieben CLI-Coverage-Lücken nach den\nModulen 14–16.</li>\n<li>Neuer Listen-Befehl\n<code>wp creacaptcha watchlist add|remove|list|clear</code> für die\nCode-Challenge-Watchlist (<code>code_challenge_watchlist</code>).</li>\n<li><code>wp creacaptcha status</code> zeigt sechs zusätzliche Zeilen:\nForm-Plugin- Toggles (CF7, Forminator, WPForms, WooCommerce + gruppierte\nZeile für die vier Woo-Sub-Toggles) und den\nWatchlist-Eintragszähler.</li>\n<li><code>wp creacaptcha enable code-challenge</code> /\n<code>disable code-challenge</code> togglet\n<code>code_challenge_enabled</code> über <code>feature_map()</code>.\nDoc-Strings von <code>enable</code>/<code>disable</code> listen jetzt\nalle 19 Features (vorher 12, fehlten WPForms, WooCommerce und die vier\nwc-* Mappings).</li>\n<li><code>wp creacaptcha settings set</code> unterstützt jetzt\nzusätzlich die Feldtypen <code>text</code>, <code>color</code> und\n<code>textblock</code> — damit werden die Widget-Customization-Felder\n(<code>widget_floating_anchor</code>, <code>widget_primary_color</code>,\n<code>widget_custom_css</code>, <code>widget_strings_override</code>)\nüber die CLI setzbar. Verworfene JSON-/Hex-Werte werden via\n<code>WP_CLI::warning()</code> gemeldet.</li>\n<li><code>wp creacaptcha doctor</code> ergänzt einen GD-Extension-Check:\nwenn <code>code_challenge_enabled</code> aktiv ist, muss die\nPHP-GD-Extension geladen sein (sonst <code>error</code> mit Exit-Code\n1).</li>\n<li><code>wp creacaptcha log list</code> unterstützt jetzt\n<code>--fields=</code> (WP-CLI- Standard); Default-Output bleibt die\nbisherige 4-Spalten-Übersicht, verfügbar werden alle 15 Spalten der\nEvent-Log-Tabelle.</li>\n<li>Neuer Befehl <code>wp creacaptcha log show &lt;id&gt;</code> zeigt\neinen einzelnen Event mit allen 15 Spalten als Key-Value-Tabelle (oder\nJSON/YAML/CSV via <code>--format</code>).</li>\n</ul>\n<h3 id=\"section-14\">0.23.0</h3>\n<ul>\n<li>WPForms-Integration: Neues Setting „WPForms schützen” im\nFormulare-Tab. Aktiv, sobald das WPForms-Plugin installiert ist.\nAuto-Inject des Widgets vor dem Submit-Button\n(<code>wpforms_display_submit_before</code>); Verify über\n<code>wpforms_process</code>-Action, Fehlerausgabe via\n<code>wpforms()-&gt;process-&gt;errors[$form_id]['header']</code>.</li>\n<li>WooCommerce-Integration: Master-Toggle „WooCommerce schützen” plus\nvier Sub-Toggles für Checkout, My-Account-Login,\nMy-Account-Registrierung und Lost-Password. Auto-Inject auf den nativen\nWoo-Hooks (<code>woocommerce_review_order_before_submit</code>,\n<code>woocommerce_login_form_end</code>,\n<code>woocommerce_register_form</code>,\n<code>woocommerce_lostpassword_form</code>); Verify auf\n<code>woocommerce_after_checkout_validation</code>,\n<code>woocommerce_process_login_errors</code>,\n<code>woocommerce_registration_errors</code>.</li>\n<li>Lost-Password ist Render-only: Server-Verifikation läuft über\n<code>protect_password_reset</code> (WordPress-Kernformular), weil\nWoo-Lost-Password über WP-Core <code>retrieve_password()</code>\nzurückläuft und damit <code>lostpassword_post</code> feuert.</li>\n<li>Produkt-Bewertungen werden bewusst nicht über einen eigenen\nSub-Toggle abgebildet — Reviews sind WordPress-Kommentare und durch\n<code>protect_comments</code> abgedeckt; der Hilfetext am Master-Toggle\nweist darauf hin.</li>\n<li>Render-Override-Filter (alle fünf, einheitliche\n<code>(bool, int $form_id)</code>- Signatur):\n<code>creationell_captcha_wpforms_autoinject</code>,\n<code>creationell_captcha_wc_checkout_autoinject</code>,\n<code>creationell_captcha_wc_login_autoinject</code>,\n<code>creationell_captcha_wc_registration_autoinject</code>,\n<code>creationell_captcha_wc_lost_password_autoinject</code>. Bei\n<code>false</code> wird das Auto-Inject übersprungen; die Verifikation\nbleibt aktiv.</li>\n<li>WP-CLI: sechs neue Feature-Schlüssel für\n<code>wp creacaptcha enable|disable</code> — <code>wpforms</code>,\n<code>woocommerce</code>, <code>wc-checkout</code>,\n<code>wc-login</code>, <code>wc-registration</code> und\n<code>wc-lost-password</code>.</li>\n<li>Bypass-Kette und Kill-Switch wirken wie bei den bestehenden\nIntegrationen: jeder Verify-Pfad ruft\n<code>creationell_captcha_request_bypassed()</code> und respektiert\n<code>CREATIONELL_CAPTCHA_DISABLE</code>.</li>\n</ul>\n<h3 id=\"section-15\">0.22.0</h3>\n<ul>\n<li>Widget-Bugfix: Der\nALTCHA-<code>&lt;altcha-widget&gt;</code>-Custom-Element-Tag erkennt nur\n9 spezifische HTML-Attribute (<code>auto</code>, <code>challenge</code>,\n<code>configuration</code>, <code>display</code>, <code>language</code>,\n<code>name</code>, <code>theme</code>, <code>type</code>,\n<code>workers</code>) — alle anderen Props (Verify-URL,\nFloating-Anchor/Placement/Offset, Code-Challenge- Display,\nHide-Footer/Logo, Strings-Override) müssen als JSON-Blob über das\n<code>configuration</code>-Attribut übergeben werden. Bisher hat das\nPlugin diese Settings als Einzelattribute emittiert, die das Widget\nstillschweigend ignoriert hat. Sichtbare Folgen: Floating-Anchor griff\nnicht, ALTCHA-Footer/Logo blieben sichtbar, Code-Challenge-Modal-Modi\n(overlay/bottomsheet) wurden ignoriert, eigene Übersetzungen waren\nwirkungslos. Mit v0.22.0 wirken alle Modul-14-Settings korrekt — das ist\neine Verhaltensänderung, falls jemand diese Felder auf Nicht- Default\ngesetzt hatte.</li>\n<li>Bild-Code-Challenge: Zweite Captcha-Stufe nach der\nProof-of-Work-Verifikation — ein vom Server ausgestelltes PNG mit einem\n4–8-stelligen Code, den der User abtippen muss. Self-hosted, kein\nexterner Dienst, kein ALTCHA Sentinel.</li>\n<li>Neue Section „Bild-Code-Challenge” im Captcha-Tab mit Master-Toggle\nund drei unabhängigen Trigger-Bedingungen: Under-Attack-Modus,\nRate-Limit- Schwellwert (konfigurierbar 50–95 %) sowie eine eigene\nWatch-Liste von IPs/CIDRs. Mehrere Trigger gleichzeitig sind\nOR-verknüpft.</li>\n<li>Code-Optionen: Länge 4–8, Zeichensatz (nur Ziffern / alphanumerisch\n/ alphanumerisch ohne Verwechsler), Token-Gültigkeit 60–900\nSekunden.</li>\n<li>Zwei neue REST-Endpoints:\n<code>GET /wp-json/creationell-captcha/v1/code-image</code> (PNG-Bild)\nund <code>POST /wp-json/creationell-captcha/v1/code-verify</code>\n(Code-Prüfung, liefert eine serverseitig gelöste ALTCHA-Payload, die\ndurch den bestehenden Verifizierungspfad geht). Tokens sind opake\nServer- Identifier (32 Hex), Code lebt nur in einem WP-Transient — kein\nClient-side-Leak des erwarteten Codes.</li>\n<li>Trigger „Immer”: Vierter Trigger-Toggle in der\nCode-Challenge-Section, damit die Code-Challenge unabhängig von\nUnder-Attack / Rate-Limit- Schwelle / Watch-Liste bei jedem\nCaptcha-Request ausgespielt wird — sinnvoll fürs lokale Testen oder\npauschal erhöhte Sicherheit. Default aus.</li>\n<li>Under-Attack-Schutz: Code-Challenge wird auf dem Under-Attack-Inter-\nstitial unterdrückt (das Interstitial-Widget ist invisible — ein Code-\nModal könnte nicht angezeigt werden). Das Interstitial hängt einen\nHMAC-signierten Kontext-Token an die challenge-URL, der nur server-\nseitig signierbar ist; ein Angreifer kann die Suppression nicht selbst\ntriggern.</li>\n<li>Das <code>&lt;altcha-widget&gt;</code> bekommt verifyUrl (sowie alle\nanderen Modul-14- Settings) via das\n<code>configuration</code>-JSON-Attribut, damit es vom Widget überhaupt\ngelesen wird.</li>\n<li>Bild-Rendering via PHP-GD mit vendorierter DejaVuSans-Bold-TTF unter\n<code>assets/fonts/captcha.ttf</code> und naiver Anti-OCR-Verzerrung\n(rotierte Zeichen, Querlinien, Rauschen). Wenn die TTF-Datei fehlt,\nfällt der Renderer auf den GD-Bitmap-Font 5 zurück.</li>\n<li>WP-CLI: <code>wp creacaptcha status</code> zeigt eine neue Zeile\n„Code-Challenge” mit dem effektiven Zustand (<code>an</code> /\n<code>aus</code> / <code>inaktiv (kein GD)</code>).</li>\n<li>Bypass-Schutz: <code>Engine::verify()</code> lehnt jeden Payload ab,\nin dem <code>parameters.data.ccode</code> gesetzt ist — verhindert, dass\nein Angreifer den ursprünglichen Code-Challenge-Payload direkt am\nForm-Submit vorbei einreicht. Frische Payloads aus\n<code>Engine::issue_signed_payload()</code> haben kein\n<code>data.ccode</code> und passieren den Filter.</li>\n<li>Wenn die PHP-GD-Extension fehlt, deaktiviert sich das Feature\nstillschweigend, der bestehende PoW-Flow bleibt unangetastet, und in der\nSettings-Section erscheint eine Warn-Notice.</li>\n</ul>\n<h3 id=\"section-16\">0.21.0</h3>\n<ul>\n<li>Widget: Vendoriert jetzt das ALTCHA-Basis-Stylesheet\n(<code>dist/external/altcha.css</code>) und die sieben Theme-CSS-Files\n(<code>dist/themes/*.min.css</code>). Ohne diese fehlten alle\nDisplay-Modus-Positionierungen (floating/overlay/bar) komplett, und das\nTheme-Attribut hatte keinen sichtbaren Effekt.</li>\n<li>Widget: <code>widget_display</code>-Option <code>bottomsheet</code>\nentfernt — der Wert war kein gültiger ALTCHA-<code>display</code>-Modus\n(nur Inline-Fallback auf standard). Stattdessen neues Setting\n<code>widget_code_challenge_display</code>\n(standard/overlay/bottomsheet) für die ALTCHA-Code-Challenge-Modal, wo\n<code>bottomsheet</code> tatsächlich hingehört.</li>\n<li>Widget: Drei neue Settings für den schwebenden Modus:\n<code>widget_floating_anchor</code> (CSS-Selektor, leer = erster\nSubmit-Button), <code>widget_floating_placement</code>\n(auto/top/bottom), <code>widget_floating_offset</code> (px, 0-200). Ohne\nAnchor bleibt das schwebende Widget off-screen — Help-Text macht das\njetzt klar.</li>\n<li>Update-Procedure für das Widget-Asset auf einen abgesicherten\nnpm-Bezug umgestellt (Schutz vor kompromittierten npm-Paketen).</li>\n<li>Architektur: Neuer Field-Type <code>text</code> (single-line input)\nfür CSS-Selektor- und ähnliche String-Settings.</li>\n</ul>\n<h3 id=\"section-17\">0.20.0</h3>\n<ul>\n<li>Widget: Acht neue Customization-Settings unter „Captcha →\nWidget-Erscheinungsbild”. Display-Modus (standard, floating, overlay,\nbar, invisible, bottomsheet), Interaktions-Typ (checkbox/switch/native),\nautomatische Auslösung (none/onload/onsubmit), eines der acht\nALTCHA-v3-Themes, optionales Ausblenden des ALTCHA-Brandings,\nAkzentfarbe per Color-Picker, eigenes CSS und JSON-Override für die\nWidget-Texte.</li>\n<li>Widget: Das alte zusammengesetzte <code>widget_mode</code>-Setting\n(visible/auto/overlay) entfällt; ein Upgrade-Hook migriert beim ersten\nAdmin-Aufruf automatisch auf die neuen Keys (<code>visible</code> →\nstandard+none, <code>auto</code> → invisible+onload,\n<code>overlay</code> → floating+onsubmit).</li>\n<li>Widget: Der overlay-Modus aus Modul 11a wird jetzt korrekt mit der\nv3- Syntax <code>display=\"floating\"</code> ausgespielt (vorher\nveraltetes <code>floating=\"auto\"</code>).</li>\n<li>Widget: Inline-CSS-Variable\n<code>--creationell-captcha-primary</code> überschreibt die\nALTCHA-Standard-Akzentfarbe, wenn <code>widget_primary_color</code>\ngesetzt ist. Eigenes CSS wird direkt danach ausgegeben und kann beliebig\nüberschreiben.</li>\n<li>WP-CLI: <code>wp creacaptcha status</code> zeigt eine neue Zeile\n„Widget-Anzeige” mit dem aktiven Display-Modus.</li>\n<li>Architektur: Zwei neue Field-Typen <code>color</code> und\n<code>textblock</code> ergänzen das Settings-Framework.\n<code>textblock</code> speichert mehrzeiligen Text ohne die\nLine-Listen-Semantik des bisherigen <code>textarea</code>-Typs.</li>\n</ul>\n<h3 id=\"section-18\">0.19.0</h3>\n<ul>\n<li>WP-CLI: Fünf neue Listen-Subbefehle für die seit v0.13.0\nhinzugekommenen Listen-Settings —\n<code>wp creacaptcha trusted-proxies|bypass-ua|bypass-cookies|actions|inject-paths</code>,\njeweils mit <code>add|remove|list|clear</code>. Damit sind alle Listen\nüber dedizierte Befehle pflegbar, ohne den Umweg über\n<code>settings set</code>.</li>\n<li>WP-CLI: Neue Subcommand-Gruppe\n<code>wp creacaptcha cloudflare</code> mit\n<code>refresh</code>/<code>clear</code>/<code>status</code>. Der alte\nTop-Level-Befehl <code>wp creacaptcha refresh-cloudflare-ips</code>\nbleibt als Deprecation-Alias erhalten (Entfernung frühestens\nv1.0.0).</li>\n<li>WP-CLI: Neuer Diagnose-Befehl\n<code>wp creacaptcha test-bypass</code>, simuliert die Bypass-Auswertung\nmit <code>--ip</code>/<code>--ua</code>/<code>--cookie</code>-Flags.\nExit 0 bei Bypass, Exit 1 sonst.</li>\n<li>WP-CLI: Neuer Diagnose-Befehl <code>wp creacaptcha doctor</code> mit\n9 Pflicht-Checks (Vendored Library, HMAC-Secrets, Event-Log-Tabelle,\nCloudflare-Refresh-Cron, Kill-Switch, Captcha-Plugin-Konflikte,\nPHP-Version, Cloudflare-Cache-Alter, Settings-Defaults). Erweiterbar\nüber den Filter <code>creationell_captcha_doctor_checks</code>.</li>\n<li>WP-CLI: <code>wp creacaptcha status</code> listet jetzt auch die\nfünf neuen Listen mit Eintragszählern.</li>\n<li>Werkzeuge-Seite: Neuer fünfter Block „Cloudflare-IP-Cache” mit\nStatus (gecachte v4/v6-Ranges, letzter Refresh, nächster Cron-Run,\nQuelle) und zwei Buttons („Jetzt aktualisieren”, „Cache leeren”). Beide\nButtons rufen exakt die gleichen Helfer wie die CLI.</li>\n<li>Refactor: Die feldspezifische Validierung für Action-Patterns und\nBypass-Cookies wurde aus\n<code>creationell_captcha_sanitize_settings()</code> in zwei\nwiederverwendbare Helfer extrahiert — Charset-Änderungen sind jetzt an\neiner Stelle gepflegt. Außerdem wurde <code>request_bypassed()</code> in\neine reine <code>evaluate_bypass(?ip, ?ua, cookies)</code> plus dünnen\nGlobals-Wrapper aufgeteilt; alle bestehenden Aufrufer bleiben\nunverändert.</li>\n</ul>\n<h3 id=\"section-19\">0.18.0</h3>\n<ul>\n<li>Interceptor: Drei neue Mechaniken. Die Pfad-Liste\n(<code>Geschützte Pfade</code>) unterstützt jetzt <code>!</code>-Präfix\nfür Ausschluss-Muster (Allow-Liste mit Ausnahmen), z. B.\n<code>/forms/*</code> zusammen mit <code>!/forms/whitelisted</code>.\nEine neue Liste <code>Geschützte Aktionen</code> schützt\nWordPress-Action-Endpoints (das <code>$_POST[action]</code>- oder\n<code>$_GET[action]</code>-Feld auf admin-post.php / admin-ajax.php) —\nselbst wenn diese sonst durch den <code>is_admin()</code>-Bypass\nausgenommen wären. Eine neue Liste <code>Inject-Pfade</code> injiziert\ndie Sicherheitsabfrage automatisch vor jedem <code>&lt;/form&gt;</code>\nder passenden Seiten — nützlich für Theme- oder Drittanbieter-Formulare,\ndie sich nicht direkt modifizieren lassen (idempotent: Formulare mit\nbereits eingebautem Widget werden übersprungen).</li>\n</ul>\n<h3 id=\"section-20\">0.17.0</h3>\n<ul>\n<li>Logging-Granularität: Sechs neue Backend-Checkboxes\n(<code>Erfolgreiche   Verifikationen loggen</code>,\n<code>Fehlgeschlagene Verifikationen loggen</code>,\n<code>Firewall-Blocks loggen</code>,\n<code>Rate-Limit-Blocks loggen</code>,\n<code>Under-Attack-Abfragen loggen</code>,\n<code>Ausgestellte Challenges loggen</code>) steuern, welche\nEreignistypen in den Detail-Event-Log geschrieben werden. Aggregierte\nTages- und Stundenzähler erfassen alle Typen unabhängig davon.\nPer-Default sind die ersten fünf an,\n<code>Ausgestellte Challenges   loggen</code> ist aus\n(hochvolumig).</li>\n<li>Neuer Ereignistyp <code>challenge</code> — wird bei jedem\nREST-Aufruf der Challenge-Route gefeuert. Im Statistik-Dashboard\nerscheint die neue Kachel/Spalte „Challenges ausgestellt”\nautomatisch.</li>\n<li>Request-Body-Fingerabdruck: Optionaler neuer Schalter\n<code>Request-Body-Fingerabdruck speichern</code>. Wenn aktiv, wird pro\nEvent-Log-Zeile eine JSON-Map aus Feldnamen und Wertlängen mit abgelegt\n— ohne die Werte selbst. Hilft bei der Angriffsmuster-Analyse, ohne PII\nzu speichern.</li>\n<li>IP-Anonymisierung: Optionaler neuer Schalter\n<code>IP-Adressen anonymisieren</code> trunkiert IPv4-Adressen auf das\nletzte Oktett und IPv6 auf die letzten 80 Bit, bevor sie in den\nEvent-Log geschrieben werden — DSGVO-konform.</li>\n</ul>\n<h3 id=\"section-21\">0.16.0</h3>\n<ul>\n<li>Bypass: Neue Backend-Sektion „Bypass” im Firewall-Tab mit drei\nEintragsarten, die jeweils Firewall, Rate-Limiter, Captcha und\nUnder-Attack-Modus gleichermaßen umgehen — die bisherige\nIP-Erlaubnisliste (jetzt global), eine User-Agent-Wildcard-Liste und\neine Cookie-Bypass-Liste im Format „name=wert”. Bypass-Treffer auf\nFormular-Ebene erscheinen im Event-Log als <code>verified</code>-Eintrag\nmit passendem Grund (IP-Allowlist / UA-Bypass / Cookie-Bypass).</li>\n<li>Widget: Dritter Anzeigemodus „Schwebendes Overlay” — die\nSicherheits- abfrage erscheint als kleines Pop-up über dem Submit-Button\nund löst beim Submit automatisch.</li>\n</ul>\n<h3 id=\"section-22\">0.15.0</h3>\n<ul>\n<li>Firewall/IP-Erkennung: Der weitergeleitete Header (X-Forwarded-For,\nX-Real-IP, CF-Connecting-IP, True-Client-IP) wird nur noch dann\nbeachtet, wenn die direkte Verbindung aus einem vertrauenswürdigen Hop\nkommt. Neue Sektion „Proxy &amp; IP-Ermittlung” im Firewall-Tab mit\nTextarea für vertrauenswürdige Proxies, Toggles für Private-Netze und\nCloudflare und optionalem täglichem Cron-Refresh der CF-Ranges.\nCloudflare-Snapshot wird mitgeliefert. Die Trust-Liste lässt sich\nzusätzlich über die wp-config-Konstante\n<code>CREATIONELL_CAPTCHA_TRUSTED_PROXIES</code> ergänzen. Bei aktivem\nProxy-Modus ohne konfigurierte Trust-Quelle erscheint im Backend ein\nHinweis. Neuer WP-CLI-Befehl\n<code>wp creacaptcha refresh-cloudflare-ips</code>.</li>\n</ul>\n<h3 id=\"section-23\">0.14.0</h3>\n<ul>\n<li>Statistik: Die Statistik-Seite hat einen „↻ Aktualisieren”-Button.\nDer „Ereignisse”-Tab erfasst je Ereignis zusätzlich Plugin/Integration,\nAktion, Formular-ID, Auslöser-Grund, User-Agent, Referrer, Benutzer-ID\nund die eingereichten Verifizierungsdaten, zeigt eine erweiterte\nSpaltenauswahl und öffnet pro Zeile ein Detail-Fenster mit allen\nerfassten Feldern. Der CSV-Export enthält die neuen Felder.</li>\n</ul>\n<h3 id=\"section-24\">0.13.0</h3>\n<ul>\n<li>WP-CLI: neue Befehlsgruppe <code>wp creacaptcha …</code> für Status,\nDiagnose, Statistik, Einstellungen\n(lesen/setzen/exportieren/importieren/zurücksetzen), Modul-Aktivierung,\nPflege der IP- und User-Agent-Listen, Verwaltung des Event-Logs und eine\nReparatur-Routine.</li>\n<li>Backend: neue Seite <strong>CreaCaptcha → Werkzeuge</strong> zum\nExportieren und Importieren der Einstellungen, für einen vollständigen\nReset auf Werkseinstellungen sowie zum Laden der Standardwerte unter\nBeibehaltung der gepflegten Listen.</li>\n</ul>\n<h3 id=\"section-25\">0.12.0</h3>\n<ul>\n<li>Statistik: Der „Ereignisse”-Tab hat jetzt eine Filter-Leiste —\nFreitextsuche über IP-Adresse und Pfad, Filter nach Ereignistyp und ein\nVon/Bis-Datumsbereich —, blättert seitenweise durch alle aufgezeichneten\nEreignisse und bietet einen CSV-Export der jeweils gefilterten\nEreignismenge zur weiteren Analyse.</li>\n</ul>\n<h3 id=\"section-26\">0.11.0</h3>\n<ul>\n<li>Statistik: Die Statistik-Seite ist jetzt ein Dashboard mit drei Tabs\n(Übersicht, Verlauf, Ereignisse). Der „Übersicht”-Tab zeigt KPI-Kacheln\nfür den 24-Stunden-Blick und eine Vergleichstabelle über vier\nZeitfenster (24 Stunden, 7 Tage, 30 Tage, 90 Tage); ein neuer\nstündlicher Zähler liefert die Daten für das 24-Stunden-Fenster.</li>\n</ul>\n<h3 id=\"section-27\">0.10.0</h3>\n<ul>\n<li>Backend: Die Einstellungsseite ist jetzt in sechs thematische Tabs\ngegliedert (Captcha, Formulare, Firewall, Under-Attack, E-Mail-Schutz,\nAnalytics) statt einer langen Liste — übersichtlicher, mit weiterhin\neinem gemeinsamen „Änderungen speichern” für alle Tabs.</li>\n</ul>\n<h3 id=\"section-28\">0.9.0</h3>\n<ul>\n<li>E-Mail-Schutz: zusätzlicher Ganzseiten-Buffer-Modus, der das gesamte\nSeiten-HTML verarbeitet und damit auch theme-hart-kodierte\n<code>mailto:</code>-Links und Adressen (z. B. in Footer-Templates)\nverschleiert; der Modus ist unter „Einstellungen → CreaCaptcha →\nE-Mail-Schutz” wählbar.</li>\n</ul>\n<h3 id=\"section-29\">0.8.0</h3>\n<ul>\n<li>E-Mail-Obfuskation: <code>mailto:</code>-Links und\nKlartext-E-Mail-Adressen in Inhalten, Auszügen, Text-Widgets und\nKommentaren werden im Seitenquelltext verschleiert und per JavaScript\nerst im Browser wiederhergestellt; ohne JavaScript erscheint ein\nneutraler Platzhalter.</li>\n</ul>\n<h3 id=\"section-30\">0.7.0</h3>\n<ul>\n<li>Analytics &amp; Event-Logging: datenschutzfreundliche aggregierte\nTageszähler je Ereignistyp und ein Statistik-Dashboard; optional ein\ndetaillierter Event-Log (eigene Tabelle, IP-Adressen) mit\nkonfigurierbarer Aufbewahrung.</li>\n</ul>\n<h3 id=\"section-31\">0.6.0</h3>\n<ul>\n<li>Under-Attack-Modus: ein einschaltbarer Notfall-Modus, der jeden\nanonymen Besucher per Interstitial-Proof-of-Work-Abfrage prüft, bevor er\ndie Website erreicht; ein zeitlich begrenzter, signierter Pass-Cookie\nlässt geprüfte Besucher danach frei surfen.</li>\n</ul>\n<h3 id=\"section-32\">0.5.0</h3>\n<ul>\n<li>Firewall &amp; Rate-Limiting: IP-Blockliste/-Erlaubnisliste (inkl.\nCIDR-Bereiche), User-Agent-Blockliste und ein per-IP-Rate-Limiter mit\nwählbarem Wirkungsbereich. Beide laufen als frühe Request-Guards, mit\nProxy-Modus für die Client-IP-Ermittlung.</li>\n</ul>\n<h3 id=\"section-33\">0.4.0</h3>\n<ul>\n<li>Integrationen für Contact Form 7 und Forminator: automatischer\nProof-of-Work-Schutz für die Formulare beider Plugins, mit\n<code>[creationell_captcha]</code>-Platzhalter zur Positionierung und je\neinem Einstellungs-Schalter.</li>\n</ul>\n<h3 id=\"section-34\">0.3.0</h3>\n<ul>\n<li>Interceptor-Modul: generischer serverseitiger Request-Schutz für\neigene Formular-Pfade (<code>*</code>-Wildcards, fail-closed), Shortcode\n<code>[creationell_captcha]</code> und Template-Tag\n<code>creationell_captcha_widget()</code> zum Einbau des Widgets in\nbeliebige Formulare.</li>\n</ul>\n<h3 id=\"section-35\">0.2.0</h3>\n<ul>\n<li>Captcha-Mechanik: Proof-of-Work-Sicherheitsabfrage (PBKDF2/SHA-256\noder Argon2id), Challenge-REST-Endpoint, gebündelte\nALTCHA-Widget-Web-Component, Replay-Schutz und Schutz der vier\nWordPress-Kernformulare.</li>\n</ul>\n<h3 id=\"section-36\">0.1.0</h3>\n<ul>\n<li>Erstes Grundgerüst: Plugin-Bootstrap, Settings-API-Seite, gebündelte\nALTCHA-Bibliothek (Composer + Strauss) und\nSelf-Hosted-GitHub-Updater.</li>\n</ul>\n",
    "faq": "<h3 id=\"sendet-creacaptcha-daten-an-externe-dienste\">Sendet CreaCaptcha\nDaten an externe Dienste?</h3>\n<p>Nein. Das Plugin arbeitet vollständig selbst-gehostet — es gibt keine\nAPI-Aufrufe, kein Telemetrie-Backend, keinen Lizenz-Check und keine\nSaaS-Anbindung. Die einzige optionale externe Anfrage ist der\nCloudflare-IP-Refresh aus den offiziellen Cloudflare-Listen, der\nausschließlich auf expliziten Toggle läuft.</p>\n<h3 id=\"welcher-captcha-algorithmus-läuft-im-hintergrund\">Welcher\nCaptcha-Algorithmus läuft im Hintergrund?</h3>\n<p>CreaCaptcha nutzt die offizielle MIT-Bibliothek\n<code>altcha-org/altcha</code>. Standardmäßig kommt PBKDF2/SHA-256 zum\nEinsatz (kein PHP-Extension-Bedarf). Optional lässt sich auf Argon2id\numschalten, dafür wird <code>ext-sodium</code> benötigt.</p>\n<h3 id=\"funktioniert-das-plugin-ohne-javascript\">Funktioniert das Plugin\nohne JavaScript?</h3>\n<p>Nein — die Proof-of-Work-Sicherheitsabfrage muss vom Browser gelöst\nwerden. Ohne JavaScript erscheint das Widget als Hinweistext, und die\nServer-Verifikation wird die Submission abweisen. Für ein vollständig\nJS-loses Schutz-Setup ist die Firewall+Rate-Limit-Schicht der richtige\nAnsatz.</p>\n<h3 id=\"welche-form-plugins-werden-unterstützt\">Welche Form-Plugins\nwerden unterstützt?</h3>\n<p>Mit dedizierten Integrationen: <strong>Contact Form 7</strong>,\n<strong>Forminator</strong>, <strong>WPForms</strong> (Lite und Pro),\n<strong>WooCommerce</strong> (Checkout, My-Account-Login, Registrierung,\nLost-Password). Beliebige andere Formulare lassen sich über\n<code>[creationell_captcha]</code> und die Geschützte-Pfade-Liste\nabsichern. Für AJAX-/Admin-Post-Endpoints gibt es zusätzlich die\nGeschützte-Aktionen-Liste.</p>\n<h3\nid=\"wie-schütze-ich-ein-eigenes-formular-auf-einer-beliebigen-seite\">Wie\nschütze ich ein eigenes Formular auf einer beliebigen Seite?</h3>\n<p>Drei Schritte: (1) Den Shortcode <code>[creationell_captcha]</code>\noder das Template-Tag <code>creationell_captcha_widget()</code> ins\nFormular einbauen. (2) Den Pfad der Seite oder den Submit-Pfad in\n<strong>Captcha → Interceptor → Geschützte Pfade</strong> eintragen. (3)\nBei AJAX-/Admin-Post-Submissions zusätzlich den\n<code>action</code>-Namen in <strong>Geschützte Aktionen</strong>. Der\nInterceptor verifiziert dann automatisch jede Submission.</p>\n<h3 id=\"was-passiert-mit-ungelösten-bot-submissions\">Was passiert mit\nungelösten Bot-Submissions?</h3>\n<p>Der Server lehnt die Submission ab. Bei klassischen Formularen erhält\nder Browser die normale Validierungs-Fehlermeldung des jeweiligen\nPlugins. Bei AJAX wird <code>403 Forbidden</code> mit JSON-Body\ngeliefert. Der Bot bekommt keine Hilfe in Form von Hinweisen, woran das\nCaptcha gescheitert ist — der <code>reason</code> landet nur im\nEvent-Log.</p>\n<h3\nid=\"wie-kann-ich-mich-selbst-aussperren-und-wie-komme-ich-wieder-rein\">Wie\nkann ich mich selbst aussperren — und wie komme ich wieder rein?</h3>\n<p>Wer durch eigene Firewall-Regeln, Rate-Limit oder einen kaputten\nUnder-Attack-Modus ausgesperrt wird, kann zu jeder Zeit per\n<code>wp-config.php</code> den Kill-Switch setzen:</p>\n<div class=\"sourceCode\" id=\"cb1\"><pre\nclass=\"sourceCode php\"><code class=\"sourceCode php\"><span id=\"cb1-1\"><a href=\"#cb1-1\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"fu\">define</span>( <span class=\"st\">&#39;CREATIONELL_CAPTCHA_DISABLE&#39;</span><span class=\"ot\">,</span> <span class=\"kw\">true</span> )<span class=\"ot\">;</span></span></code></pre></div>\n<p>Sofort sind <strong>alle</strong> Module aus — Firewall, Rate-Limit,\nCaptcha, Under-Attack, Interceptor. Anschließend lassen sich die\nproblematischen Einstellungen im Backend korrigieren. Ohne\nSSH/FTP-Zugriff bleibt der direkte Datenbank-Eingriff:\n<code>wp option update creationell_captcha_settings …</code> oder per\n<code>wp creacaptcha settings load-defaults</code>.</p>\n<h3\nid=\"funktioniert-das-plugin-hinter-cloudflare-oder-einem-reverse-proxy\">Funktioniert\ndas Plugin hinter Cloudflare oder einem Reverse-Proxy?</h3>\n<p>Ja. Im Tab <strong>Firewall</strong> unter „Proxy &amp;\nIP-Ermittlung” den Proxy-Modus aktivieren und den passenden\nForwarded-Header wählen. Für Cloudflare zusätzlich „Cloudflare-IPs\nvertrauen” und optional den Auto-Refresh einschalten — die offiziellen\nCloudflare-v4/v6-Ranges werden dann täglich neu geladen. Ohne\nTrust-Konfiguration wird der Header ignoriert, damit Angreifer nicht\nbeliebige IPs spoofen können.</p>\n<h3 id=\"wie-viel-performance-kostet-das-plugin\">Wie viel Performance\nkostet das Plugin?</h3>\n<p>Sehr wenig. Die Captcha-Berechnung läuft im Browser, nicht auf dem\nServer. Die Firewall-Auswertung ist eine reine IP-/Pattern-Prüfung\n(keine externen Lookups). Analytics-Counter werden seit v0.26.0 pro\nRequest gesammelt und in einem einzigen DB-Roundtrip auf\n<code>shutdown</code> geschrieben. Das Event-Log nutzt seit derselben\nVersion einen Composite-Index, der typgefilterte Dashboard-Queries ohne\nFilesort beantwortet.</p>\n<h3 id=\"wie-dsgvo-konform-ist-das-plugin\">Wie DSGVO-konform ist das\nPlugin?</h3>\n<p>Out-of-the-box ist die IP-Anonymisierung im Event-Log aktiv (IPv4 auf\nletztes Oktett, IPv6 auf letzte 80 Bit trunkiert). Aggregat-Zähler\nenthalten keinerlei personenbezogene Daten. Im Event-Log werden keine\nQuery-String-Werte (GET-Token, Magic-Links, API-Keys) gespeichert — der\nPfad wird vor dem Schreiben auf den reinen Pfadanteil reduziert.\nRequest-Body-Fingerprints enthalten nur Feldnamen und Wertlängen;\nsensitive Feldnamen werden zusätzlich gehasht.</p>\n<h3 id=\"wie-deaktiviere-ich-das-plugin-sauber\">Wie deaktiviere ich das\nPlugin sauber?</h3>\n<p>Über <strong>Plugins → Installierte Plugins</strong> deaktivieren\nreicht für den Betrieb. Wer auch die Daten loswerden will, kann das\nPlugin anschließend löschen — der <code>uninstall.php</code>-Cleanup\nentfernt alle Options, Transients (inklusive <code>_cc_*</code>-Caches\nund <code>_git_update_*</code>-Locks) sowie die Event-Tabelle.</p>\n<h3 id=\"funktioniert-das-plugin-mit-multisite\">Funktioniert das Plugin\nmit Multisite?</h3>\n<p>Ja, allerdings pro Site einzeln aktivierbar. Es gibt aktuell keine\nNetwork-Activate-Logik mit zentralen Settings — jede Site hat ihre\neigene Konfiguration. Network-weite Aktivierung ist möglich, hat aber\ndenselben Effekt wie eine Aktivierung pro Site.</p>\n<h3\nid=\"kann-ich-creacaptcha-parallel-zu-einem-anderen-captcha-plugin-betreiben\">Kann\nich CreaCaptcha parallel zu einem anderen Captcha-Plugin betreiben?</h3>\n<p>Technisch ja — die Code-Pfade kollidieren nicht.\n<code>wp creacaptcha doctor</code> prüft auf bekannte Captcha-Plugins\n(reCAPTCHA, hCaptcha, Turnstile, ALTCHA-WordPress) und warnt, weil zwei\nCaptcha-Layer auf demselben Formular für den Nutzer unzumutbar werden.\nEmpfehlung: nur eines aktiv lassen.</p>\n<h3 id=\"wo-finde-ich-logs-wenn-etwas-nicht-funktioniert\">Wo finde ich\nLogs, wenn etwas nicht funktioniert?</h3>\n<p>Mit <code>define( 'CREATIONELL_CAPTCHA_DEBUG', true );</code> (oder\nglobal <code>WP_DEBUG</code>) schreibt das Plugin Debug-Hinweise nach\n<code>wp-content/debug.log</code>. Zusätzlich liefert\n<code>wp creacaptcha doctor</code> einen kompletten Diagnose-Lauf, und\ndas Event-Log zeigt alle abgewiesenen Requests samt Grund.</p>\n<h3 id=\"wie-aktualisiere-ich-auf-eine-neue-version\">Wie aktualisiere ich\nauf eine neue Version?</h3>\n<p>Drei Wege: (1) Der eingebaute Self-Hosted-Updater zeigt neue\nVersionen automatisch im <strong>Plugins</strong>-Bildschirm — wie ein\nnormales wp.org-Update. (2) ZIP von der GitHub-Release-Seite\nherunterladen und manuell über <strong>Plugins → Installieren → Plugin\nhochladen</strong> einspielen. (3) Per WP-CLI:\n<code>wp plugin install --activate &lt;release-url&gt;</code> mit der\nURL aus den GitHub-Releases.</p>\n<hr />\n"
  },
  "readme_html": "<h1 id=\"creacaptcha\">CreaCaptcha</h1>\n<p><strong>Plugin Name:</strong> CreaCaptcha<br />\n<strong>Plugin URI:</strong>\nhttps://github.com/creationell-dev/creationell-captcha<br />\n<strong>Description:</strong> Datenschutzfreundlicher\nProof-of-Work-Captcha, Firewall, Rate-Limiter, Under-Attack-Modus,\nE-Mail-Obfuskation und Bild-Code-Challenge — vollständig selbst-gehostet\nohne externe Dienste.<br />\n<strong>Version:</strong> 1.0.1<br />\n<strong>Author:</strong> creationell® – die Werbeagentur <a\nhref=\"mailto:marketing@creationell.de\"\nclass=\"email\">marketing@creationell.de</a><br />\n<strong>Author URI:</strong> https://www.creationell.de/<br />\n<strong>Contributors:</strong> creationell-dev, JPKCom<br />\n<strong>Tags:</strong> captcha, spam, anti-spam, anti-bot, proof of\nwork<br />\n<strong>Requires at least:</strong> 6.9<br />\n<strong>Tested up to:</strong> 7.0<br />\n<strong>Requires PHP:</strong> 8.3<br />\n<strong>Stable tag:</strong> 1.0.1<br />\n<strong>License:</strong> GPL-2.0-or-later<br />\n<strong>License URI:</strong>\nhttps://www.gnu.org/licenses/gpl-2.0.html<br />\n<strong>Text Domain:</strong> creationell-captcha<br />\n<strong>Domain Path:</strong> /languages</p>\n<p>Schützt WordPress-Formulare und ganze Sites mit einem\nselbst-gehosteten Proof-of-Work-Captcha, Firewall, Rate-Limiter,\nUnder-Attack-Interstitial, E-Mail-Obfuskation und optionaler\nBild-Code-Challenge — ohne externe Dienste.</p>\n<hr />\n<h2 id=\"description\">Description</h2>\n<p><strong>CreaCaptcha</strong> ist ein vollständig selbst-gehostetes\nSchutz-Plugin für WordPress. Es kombiniert einen Proof-of-Work-Captcha\nauf Basis der MIT-Bibliothek <code>altcha-org/altcha</code> mit einer\nFirewall, einem per-IP-Rate-Limiter, einem Under-Attack-Modus,\nE-Mail-Obfuskation und einer optionalen Bild-Code-Challenge. Es gibt\nkeine externen API-Aufrufe, kein Lizenz-Gate, keine SaaS-Anbindung und\nkeine Telemetrie — alle Funktionen laufen lokal in WordPress.</p>\n<p>Das Plugin schützt die vier WordPress-Kernformulare (Kommentare,\nLogin, Registrierung, Passwort-Reset) sowie automatisch alle Formulare\ngängiger Form-Plugins (<strong>Contact Form 7</strong>,\n<strong>Forminator</strong>, <strong>WPForms</strong>,\n<strong>WooCommerce</strong> mit Checkout / My-Account-Login /\nRegistrierung / Lost-Password). Eigene oder fremde Formulare lassen sich\nüber den Shortcode <code>[creationell_captcha]</code>, das Template-Tag\n<code>creationell_captcha_widget()</code> oder den generischen\nInterceptor (Pfad-Schutz) absichern.</p>\n<h3 id=\"key-features\">Key Features</h3>\n<ul>\n<li><strong>Proof-of-Work-Captcha</strong> — Server stellt eine\nChallenge aus, Browser löst sie mit PBKDF2/SHA-256 oder Argon2id; kein\nKlick-Puzzle, keine Bilderkennung, keine Tracking-Cookies</li>\n<li><strong>Vollständig selbst-gehostet</strong> — Keine externen\nDienste, kein API-Key, kein Lizenz-Server. Datenfluss bleibt zu 100 %\nauf dem WordPress-Host</li>\n<li><strong>Schutz der WordPress-Kernformulare</strong> — Kommentare,\nLogin, Registrierung und Passwort-Reset einzeln zuschaltbar</li>\n<li><strong>Vier Form-Plugin-Integrationen</strong> — Contact Form 7,\nForminator, WPForms, WooCommerce (Checkout + My-Account-Login +\nRegistrierung + Lost-Password) mit Auto-Inject und\nServer-Verifikation</li>\n<li><strong>Generischer Interceptor</strong> — Eigene Form-Pfade per\nURL-Muster (mit <code>*</code>-Wildcards und <code>!</code>-Ausschluss)\nschützen, fail-closed</li>\n<li><strong>Action-Schutz</strong> — <code>admin-post.php</code> /\n<code>admin-ajax.php</code>-Aktionen über die <code>action</code>-Liste\nabsichern, mit <code>*</code>-Wildcards und\n<code>!</code>-Ausschluss</li>\n<li><strong>Inject-Pfade</strong> — Auf konfigurierten Pfaden wird die\nSicherheitsabfrage automatisch in jedes <code>&lt;/form&gt;</code>\ninjiziert (idempotent — bereits geschützte Formulare werden\nübersprungen)</li>\n<li><strong>Shortcode &amp; Template-Tag</strong> —\n<code>[creationell_captcha]</code> oder\n<code>creationell_captcha_widget()</code> für freihändigen Einbau in\nbeliebige Formulare; CF7-Form-Tag mit identischem Namen</li>\n<li><strong>Bild-Code-Challenge</strong> — Optionale zweite Stufe nach\nPoW: serverseitig gerendertes PNG (PHP-GD, mitgelieferte DejaVu-TTF),\n4–8-stelliger Code mit Anti-OCR-Verzerrung; Trigger wahlweise Immer,\nUnder-Attack, Rate-Limit-Schwelle oder Watch-Liste (OR-verknüpft)</li>\n<li><strong>Under-Attack-Modus</strong> — HTTP-503-Interstitial mit\ninvisiblem PoW-Widget für anonyme Besucher; HMAC-signiertes Pass-Cookie\nfür die konfigurierte Dauer</li>\n<li><strong>Firewall</strong> — IP-Blocklist &amp; -Allowlist (exakt +\nCIDR, v4 &amp; v6), User-Agent-Blocklist (Wildcard), Proxy-Modus mit\nkonfigurierbarem Forwarded-Header</li>\n<li><strong>Vertrauenswürdige Proxies</strong> — Eigene IP-/CIDR-Liste,\nCloudflare-IP-Auto-Refresh aus den offiziellen Listen, optionaler Trust\nvon Private-Netzen; nur dann wird <code>X-Forwarded-For</code>\nausgewertet</li>\n<li><strong>Rate-Limit</strong> — Per-IP Fixed-Window-Counter mit drei\nScopes (Core-Formulare / alle Formulare / global); konfigurierbarer\nMax-Wert, Fenster und Retry-After</li>\n<li><strong>Drei Bypass-Mechaniken</strong> — IP-Allowlist (CIDR),\nUser-Agent-Wildcard-Liste und Cookie-Bypass (<code>name=wert</code>);\nTreffer umgehen Firewall, Rate-Limit, Captcha und Under-Attack</li>\n<li><strong>Analytics &amp; Event-Log</strong> — Aggregierte Tages- und\nStundenzähler je Ereignistyp (<code>verified</code> /\n<code>failed</code> / <code>firewall</code> / <code>ratelimit</code> /\n<code>underattack</code> / <code>challenge</code>); optional\ndetaillierte Event-Tabelle mit IP, Pfad, Plugin, Aktion, Form-ID, Grund,\nUser-Agent, Referrer, User-ID und Request-Body-Fingerprint</li>\n<li><strong>DSGVO-konforme IP-Anonymisierung</strong> — Standard: IPv4\nauf das letzte Oktett, IPv6 auf die letzten 80 Bit trunkiert</li>\n<li><strong>Statistik-Dashboard</strong> — Drei Tabs (Übersicht /\nVerlauf / Ereignisse), vier Zeitfenster (24 h / 7 Tage / 30 Tage / 90\nTage), Filterleiste, seitenweises Blättern und CSV-Export</li>\n<li><strong>E-Mail-Obfuskation</strong> — Verschleiert\n<code>mailto:</code>-Links und Klartextadressen per XOR-Hex; zwei Modi\n(Content-Filter oder Ganzseiten-Buffer für theme-hartkodierte\nAdressen)</li>\n<li><strong>Widget-Customization</strong> — Anzeigemodus (Standard /\nschwebend / Overlay / Bar / Invisible), Interaktionstyp, Auto-Trigger,\nTheme, Branding-Toggle, Akzentfarbe, eigenes CSS und Strings-Override\nfür alle Übersetzungstexte</li>\n<li><strong>Backend-UI mit sechs Tabs</strong> — Captcha, Formulare,\nFirewall, Under-Attack, <strong>Analytics</strong>, E-Mail-Schutz —\nalles unter einem gemeinsamen „Änderungen speichern”</li>\n<li><strong>Werkzeuge-Seite</strong> — Export / Import der Einstellungen\nals JSON, vollständiger Werksreset und ein gesonderter „Standardwerte\nladen”-Schritt (Listen bleiben erhalten)</li>\n<li><strong>WP-CLI-Integration</strong> — Befehlsgruppe\n<code>wp creacaptcha</code> für Status, Diagnose, Modul-Aktivierung,\nListen, Event-Log, Cloudflare-Refresh und Bypass-Tests</li>\n<li><strong>Self-Hosted-Updater</strong> — Updates direkt aus\nGitHub-Releases mit SHA-256-Manifest-Verifikation (timing-safe\n<code>hash_equals</code>)</li>\n<li><strong>Kein Lizenz-Gate</strong> — Alle Funktionen sind dauerhaft\naktiv. GPL-2.0-or-later</li>\n</ul>\n<hr />\n<h2 id=\"installation\">Installation</h2>\n<ol type=\"1\">\n<li>Den Plugin-Ordner <code>creationell-captcha</code> nach\n<code>/wp-content/plugins/</code> hochladen — entweder als ZIP über\n<strong>Plugins → Installieren → Plugin hochladen</strong> oder per\nFTP/SSH/<code>wp plugin install</code>.</li>\n<li>Unter <strong>Plugins → Installierte Plugins</strong> das Plugin\n<strong>CreaCaptcha</strong> aktivieren.</li>\n<li>Den neuen Menüpunkt <strong>CreaCaptcha</strong> im\nWordPress-Adminbereich öffnen.</li>\n<li>Unter <strong>CreaCaptcha → Einstellungen</strong> im Tab\n<strong>Captcha</strong> den Master-Toggle prüfen (Standard: aktiv) und\nden Tab <strong>Formulare</strong> durchgehen, um\nWordPress-Kernformulare und Form-Plugins zu aktivieren.</li>\n<li>Falls eigene Formular-Pfade abgesichert werden sollen: im Tab\n<strong>Captcha → Interceptor</strong> die Liste <strong>Geschützte\nPfade</strong> pflegen.</li>\n<li>Empfohlen: einmal <strong>CreaCaptcha → Statistik</strong> öffnen,\ndamit der Event-Log aktiviert werden kann (optional — die\nAggregat-Statistik läuft auch ohne).</li>\n</ol>\n<h3 id=\"anforderungen\">Anforderungen</h3>\n<ul>\n<li>WordPress <strong>6.9</strong> oder höher</li>\n<li>PHP <strong>8.3</strong> oder höher</li>\n<li>Für die Bild-Code-Challenge: PHP-Erweiterung\n<strong>GD</strong></li>\n<li>Für den optionalen Argon2id-Algorithmus: PHP-Erweiterung\n<strong>Sodium</strong></li>\n</ul>\n<p>Das Plugin prüft die Mindestversionen beim Aktivieren und zeigt im\nAdmin-Bereich eine deutliche Hinweisleiste, wenn die Umgebung zu alt\nist.</p>\n<h3 id=\"updates\">Updates</h3>\n<p>Updates kommen direkt aus dem GitHub-Repo. Der eingebaute\nSelf-Hosted-Updater (<code>includes/class-plugin-updater.php</code>)\nprüft regelmäßig das Manifest, vergleicht Versionen und installiert das\noffiziell signierte ZIP samt SHA-256-Checksum.</p>\n<hr />\n<h2 id=\"dokumentation\">Dokumentation</h2>\n<table>\n<colgroup>\n<col style=\"width: 68%\" />\n<col style=\"width: 31%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Ressource</th>\n<th>URL</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Plugin-Dokumentation (Web)</td>\n<td>https://creationell-dev.github.io/creationell-captcha/</td>\n</tr>\n<tr class=\"even\">\n<td>Update-Manifest (JSON)</td>\n<td>https://creationell-dev.github.io/creationell-captcha/plugin_creationell-captcha.json</td>\n</tr>\n<tr class=\"odd\">\n<td>API-Referenz (PHPDoc)</td>\n<td>https://creationell-dev.github.io/creationell-captcha/docs/api/</td>\n</tr>\n</tbody>\n</table>\n<p>Das Plugin aktualisiert sich über das Update-Manifest selbst — es ist\nkein Eintrag im WordPress.org-Plugin-Verzeichnis erforderlich.</p>\n<hr />\n<h2 id=\"konfiguration\">Konfiguration</h2>\n<p>Sämtliche Einstellungen liegen unter <strong>CreaCaptcha →\nEinstellungen</strong> und sind in sechs Tabs gegliedert. Alle Tabs\nteilen ein gemeinsames „Änderungen speichern”.</p>\n<h3 id=\"tab-captcha\">Tab: Captcha</h3>\n<p>Steuert die Proof-of-Work-Engine, das Widget-Aussehen und die\nBild-Code-Challenge.</p>\n<h4 id=\"section-engine\">Section „Engine”</h4>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Captcha aktivieren</td>\n<td>Master-Toggle. Aus = keinerlei PoW-Verifikation; alle anderen Module\nbleiben unbeeinflusst</td>\n</tr>\n<tr class=\"even\">\n<td>Algorithmus</td>\n<td><code>pbkdf2</code> (Standard, kein PHP-Extension-Bedarf) oder\n<code>argon2id</code> (benötigt <code>ext-sodium</code>)</td>\n</tr>\n<tr class=\"odd\">\n<td>Schwierigkeit</td>\n<td>Anzahl PoW-Iterationen; Standard 50.000 (≈ 1 s auf\nMittelklasse-Hardware)</td>\n</tr>\n<tr class=\"even\">\n<td>Challenge-Gültigkeit</td>\n<td>Sekunden, in denen eine ausgestellte Challenge eingelöst werden kann\n(Replay-Schutz)</td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"section-wordpress-kernformulare\">Section\n„WordPress-Kernformulare”</h4>\n<p>Vier unabhängige Toggles für Kommentare, Login, Registrierung und\nPasswort-Reset.</p>\n<h4 id=\"section-widget-erscheinungsbild\">Section\n„Widget-Erscheinungsbild”</h4>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Anzeigemodus</td>\n<td><code>standard</code> / <code>floating</code> (schwebend über\nSubmit-Button) / <code>overlay</code> / <code>bar</code> /\n<code>invisible</code></td>\n</tr>\n<tr class=\"even\">\n<td>Interaktionstyp</td>\n<td><code>checkbox</code> / <code>switch</code> /\n<code>native</code></td>\n</tr>\n<tr class=\"odd\">\n<td>Auto-Trigger</td>\n<td><code>none</code> / <code>onload</code> / <code>onsubmit</code></td>\n</tr>\n<tr class=\"even\">\n<td>Theme</td>\n<td>Eines der acht ALTCHA-v3-Themes</td>\n</tr>\n<tr class=\"odd\">\n<td>ALTCHA-Branding ausblenden</td>\n<td>Versteckt Footer und Logo</td>\n</tr>\n<tr class=\"even\">\n<td>Akzentfarbe</td>\n<td>Color-Picker; wird als CSS-Variable\n<code>--creationell-captcha-primary</code> ausgespielt</td>\n</tr>\n<tr class=\"odd\">\n<td>Eigenes CSS</td>\n<td>Wird inline nach dem Theme-CSS ausgegeben — beliebige\nÜberschreibungen möglich</td>\n</tr>\n<tr class=\"even\">\n<td>Übersetzungstexte überschreiben</td>\n<td>JSON-Map zum Überschreiben einzelner Widget-Strings</td>\n</tr>\n<tr class=\"odd\">\n<td>Floating-Anchor</td>\n<td>CSS-Selektor für den Anker des schwebenden Modus (leer = erster\nSubmit-Button)</td>\n</tr>\n<tr class=\"even\">\n<td>Floating-Position</td>\n<td><code>auto</code> / <code>top</code> / <code>bottom</code></td>\n</tr>\n<tr class=\"odd\">\n<td>Floating-Offset</td>\n<td>Abstand in Pixel (0–200)</td>\n</tr>\n</tbody>\n</table>\n<p>Die Floating-Felder sind nur aktiv, wenn der Anzeigemodus auf\n<strong>schwebend</strong> steht — sonst werden sie ausgegraut.</p>\n<p><strong>Sprache:</strong> CreaCaptcha erkennt die Widget-Sprache\nautomatisch aus der WordPress-Locale (<code>get_locale()</code>) und\nenqueued die passende von 20 vendorierten ALTCHA-Locale-Dateien (DE, EN,\nFR-FR/CA, ES-ES/419, IT, NL, PT-PT/BR, PL, CS, SK, DA, SV, FI, NB, HU,\nRO, EL). Eine nicht abgedeckte WP-Locale lässt das Widget auf seine\neigene <code>&lt;html lang&gt;</code>/Browser-Sprach-Detection bzw.\nEnglisch zurückfallen. Einzelne Begriffe lassen sich weiterhin über das\nSetting <strong>Übersetzungstexte überschreiben</strong> anpassen —\nAuto-Locale und Override greifen kombiniert, der Override gewinnt pro\nSchlüssel.</p>\n<h4 id=\"section-bild-code-challenge\">Section „Bild-Code-Challenge”</h4>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Code-Challenge aktivieren</td>\n<td>Master-Toggle. Benötigt PHP-GD</td>\n</tr>\n<tr class=\"even\">\n<td>Trigger: Immer</td>\n<td>Spielt die Code-Challenge bei jedem Captcha-Request aus (Test /\npauschal erhöhte Sicherheit)</td>\n</tr>\n<tr class=\"odd\">\n<td>Trigger: Under-Attack-Modus</td>\n<td>Greift nur bei aktivem Under-Attack-Modus (außer auf dem\nInterstitial selbst — dort ist sie unterdrückt)</td>\n</tr>\n<tr class=\"even\">\n<td>Trigger: Rate-Limit-Schwelle</td>\n<td>Greift, sobald die IP die Rate-Limit-Auslastung von 50–95 %\nüberschreitet</td>\n</tr>\n<tr class=\"odd\">\n<td>Trigger: Watch-Liste</td>\n<td>IPs/CIDRs, die immer eine Code-Challenge bekommen</td>\n</tr>\n<tr class=\"even\">\n<td>Code-Länge</td>\n<td>4–8 Zeichen</td>\n</tr>\n<tr class=\"odd\">\n<td>Zeichensatz</td>\n<td>Nur Ziffern / alphanumerisch / alphanumerisch ohne Verwechsler (0-O,\n1-I-l)</td>\n</tr>\n<tr class=\"even\">\n<td>Token-Gültigkeit</td>\n<td>60–900 Sekunden</td>\n</tr>\n<tr class=\"odd\">\n<td>Anzeige-Modus</td>\n<td><code>standard</code> / <code>overlay</code> /\n<code>bottomsheet</code> (im Modal des Widgets)</td>\n</tr>\n</tbody>\n</table>\n<p>Mehrere Trigger sind OR-verknüpft. Wenn die Code-Challenge\neingerichtet, aber GD nicht verfügbar ist, deaktiviert sich das Feature\nstillschweigend und zeigt eine Warn-Notice.</p>\n<h4 id=\"section-interceptor\">Section „Interceptor”</h4>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Geschützte Pfade</td>\n<td>URL-Pfade mit <code>*</code>-Wildcard. <code>!</code>-Präfix kehrt\ndas Muster um (Ausschluss). Eine Zeile pro Muster</td>\n</tr>\n<tr class=\"even\">\n<td>Geschützte Aktionen</td>\n<td>WordPress-Action-Namen für\n<code>admin-post.php</code>/<code>admin-ajax.php</code>\n(<code>$_POST[action]</code> / <code>$_GET[action]</code>).\n<code>*</code> und <code>!</code> werden unterstützt. Überschreibt den\n<code>is_admin</code>-Bypass</td>\n</tr>\n<tr class=\"odd\">\n<td>Inject-Pfade</td>\n<td>Pfade, auf denen die Sicherheitsabfrage automatisch vor jedem\n<code>&lt;/form&gt;</code> eingefügt wird (idempotent)</td>\n</tr>\n<tr class=\"even\">\n<td>Bei eingeloggten Usern überspringen</td>\n<td>Bypass für angemeldete User mit\n<code>edit_posts</code>-Capability</td>\n</tr>\n</tbody>\n</table>\n<p>Der Interceptor läuft als früher Request-Guard auf <code>init</code>\nund arbeitet <strong>fail-closed</strong>: Fehlt eine Verifikation, wird\ndie Anfrage abgelehnt (HTTP 403, AJAX-Requests bekommen JSON-403).</p>\n<h3 id=\"tab-formulare\">Tab: Formulare</h3>\n<p>Vier Toggles für die WordPress-Kernformulare (siehe Captcha-Tab —\nwerden hier als Komfort-Kopie gespiegelt) sowie sechs Toggles für die\nForm-Plugin-Integrationen.</p>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Contact Form 7 schützen</td>\n<td>Aktiv, wenn CF7 installiert ist. Auto-Inject vor Submit, Verify über\n<code>wpcf7_spam</code></td>\n</tr>\n<tr class=\"even\">\n<td>Forminator schützen</td>\n<td>Aktiv, wenn Forminator installiert ist. Auto-Inject + Verify über\n<code>forminator_custom_form_submit_errors</code></td>\n</tr>\n<tr class=\"odd\">\n<td>WPForms schützen</td>\n<td>Aktiv, wenn WPForms installiert ist. Auto-Inject vor Submit, Verify\nüber <code>wpforms_process</code></td>\n</tr>\n<tr class=\"even\">\n<td>WooCommerce schützen</td>\n<td>Master-Toggle. Aktiv, wenn WooCommerce installiert ist</td>\n</tr>\n<tr class=\"odd\">\n<td>→ Checkout schützen</td>\n<td>Auto-Inject auf <code>woocommerce_review_order_before_submit</code>,\nVerify auf <code>woocommerce_after_checkout_validation</code></td>\n</tr>\n<tr class=\"even\">\n<td>→ My-Account-Login schützen</td>\n<td>Auto-Inject auf <code>woocommerce_login_form_end</code>, Verify auf\n<code>woocommerce_process_login_errors</code></td>\n</tr>\n<tr class=\"odd\">\n<td>→ Registrierung schützen</td>\n<td>Auto-Inject auf <code>woocommerce_register_form</code>, Verify auf\n<code>woocommerce_registration_errors</code></td>\n</tr>\n<tr class=\"even\">\n<td>→ Lost-Password schützen</td>\n<td>Render-only — Server-Verify läuft über das Kern-Modul\n<code>protect_password_reset</code></td>\n</tr>\n</tbody>\n</table>\n<p>CF7 bietet zusätzlich einen Form-Tag\n<code>[creationell_captcha]</code>, mit dem die Position der\nSicherheitsabfrage frei wählbar ist. Forminator/WPForms nutzen\nAuto-Inject standardmäßig vor dem Submit-Button — der Filter\n<code>creationell_captcha_forminator_autoinject</code> (bzw.\n<code>creationell_captcha_wpforms_autoinject</code>) erlaubt das\nDeaktivieren je Formular.</p>\n<blockquote>\n<p><strong>Hinweis:</strong> WooCommerce-Produktbewertungen sind\nWordPress-Kommentare und werden bereits durch\n<strong>WordPress-Kommentare schützen</strong> abgedeckt. Es gibt\nabsichtlich keinen separaten Sub-Toggle.</p>\n</blockquote>\n<h3 id=\"tab-firewall\">Tab: Firewall</h3>\n<p>Vier Sections in dieser Reihenfolge: Proxy → Firewall → Bypass →\nRate-Limit.</p>\n<h4 id=\"section-proxy-ip-ermittlung\">Section „Proxy &amp;\nIP-Ermittlung”</h4>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Proxy-Modus</td>\n<td>Aktivieren, wenn die Site hinter einem Reverse-Proxy / CDN\nliegt</td>\n</tr>\n<tr class=\"even\">\n<td>Forwarded-Header</td>\n<td><code>X-Forwarded-For</code> (Standard) / <code>X-Real-IP</code> /\n<code>CF-Connecting-IP</code> / <code>True-Client-IP</code></td>\n</tr>\n<tr class=\"odd\">\n<td>Vertrauenswürdige Proxies</td>\n<td>IP-/CIDR-Liste, eine pro Zeile. Nur diese Hops dürfen den\nForwarded-Header setzen</td>\n</tr>\n<tr class=\"even\">\n<td>Cloudflare-IPs vertrauen</td>\n<td>Cloudflare-v4 + v6-Ranges automatisch laden</td>\n</tr>\n<tr class=\"odd\">\n<td>Cloudflare-Auto-Refresh</td>\n<td>Täglicher Cron-Refresh aus den offiziellen Cloudflare-Listen</td>\n</tr>\n<tr class=\"even\">\n<td>Private Netze vertrauen</td>\n<td>RFC1918 + ULA als trusted Hops behandeln</td>\n</tr>\n</tbody>\n</table>\n<p>Zusätzlich kann die wp-config-Konstante\n<code>CREATIONELL_CAPTCHA_TRUSTED_PROXIES</code> (Array von CIDRs) die\nTrust-Liste ergänzen.</p>\n<h4 id=\"section-firewall\">Section „Firewall”</h4>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Firewall aktivieren</td>\n<td>Master-Toggle</td>\n</tr>\n<tr class=\"even\">\n<td>IP-Blockliste</td>\n<td>Eine pro Zeile, exakt oder CIDR (v4 + v6)</td>\n</tr>\n<tr class=\"odd\">\n<td>IP-Erlaubnisliste</td>\n<td>Global wirksam: umgeht Firewall, Rate-Limiter, Captcha und\nUnder-Attack</td>\n</tr>\n<tr class=\"even\">\n<td>User-Agent-Blockliste</td>\n<td>Wildcard-Muster (z. B. <code>*bot*</code>,\n<code>*scanner*</code>)</td>\n</tr>\n</tbody>\n</table>\n<h4 id=\"section-bypass\">Section „Bypass”</h4>\n<p>Drei Eintragsarten, die jeweils Firewall, Rate-Limit, Captcha und\nUnder-Attack-Modus umgehen.</p>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>User-Agent-Erlaubnisliste</td>\n<td>Wildcard-Muster für Allow-listing (z. B. eigene\nMonitoring-Bots)</td>\n</tr>\n<tr class=\"even\">\n<td>Cookie-Bypass</td>\n<td>Liste im Format <code>name=wert</code>, eine pro Zeile</td>\n</tr>\n</tbody>\n</table>\n<p>Treffer auf Formular-Ebene erscheinen im Event-Log als\n<code>verified</code>-Eintrag mit passendem Grund (IP-Allowlist /\nUA-Bypass / Cookie-Bypass).</p>\n<h4 id=\"section-rate-limit\">Section „Rate-Limit”</h4>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Rate-Limit aktivieren</td>\n<td>Master-Toggle</td>\n</tr>\n<tr class=\"even\">\n<td>Maximale Anfragen</td>\n<td>Fixed-Window-Limit pro IP, Standard 30</td>\n</tr>\n<tr class=\"odd\">\n<td>Zeitfenster</td>\n<td>Sekunden des Fensters, Standard 300</td>\n</tr>\n<tr class=\"even\">\n<td>Wirkungsbereich</td>\n<td><code>core</code> (nur Kernformulare) / <code>forms</code> (alle\nFormulare) / <code>all</code> (global, alle Anfragen)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>edit_posts</code>-Exemption</td>\n<td>Eingeloggte User mit Schreibrechten ausnehmen</td>\n</tr>\n</tbody>\n</table>\n<p>Bei Überschreitung sendet der Plugin-Stack HTTP 429 mit\n<code>Retry-After</code>-Header.</p>\n<h3 id=\"tab-under-attack\">Tab: Under-Attack</h3>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Under-Attack aktivieren</td>\n<td>Master-Toggle. Bei <code>an</code> muss jeder anonyme Besucher eine\nPoW-Sicherheitsabfrage bestehen, bevor er die Site erreicht</td>\n</tr>\n<tr class=\"even\">\n<td>Pass-Dauer</td>\n<td>Lebenszeit des HMAC-signierten Pass-Cookies in Sekunden</td>\n</tr>\n<tr class=\"odd\">\n<td>Eingeloggte Besucher ausnehmen</td>\n<td>Standard: aktiv</td>\n</tr>\n</tbody>\n</table>\n<p><code>wp-admin</code>, REST-API und Cron sind automatisch\nausgenommen. Der Kill-Switch <code>CREATIONELL_CAPTCHA_DISABLE</code>\n(wp-config-Konstante) hebt den Modus global auf.</p>\n<h4 id=\"section-erscheinungsbild\">Section „Erscheinungsbild”</h4>\n<p>Optional — leere Felder verwenden die Standardwerte. Sichtbar, sobald\nder Under-Attack-Modus aktiv ist (sonst ausgegraut).</p>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Logo-URL</td>\n<td>Bild über der Überschrift, zentriert, Höhe ≤ 128 px. Default: kein\nLogo. Alt-Text = Website-Name. Über <code>.crea-ua-logo</code> im\nEigenes-CSS-Feld feinjustierbar</td>\n</tr>\n<tr class=\"even\">\n<td>Browser-Tab-Titel</td>\n<td><code>&lt;title&gt;</code>-Tag der Interstitial-Seite. Default:\n„Sicherheitsprüfung”</td>\n</tr>\n<tr class=\"odd\">\n<td>Überschrift</td>\n<td>Große H1 mittig auf der Seite. Default: „Die Website wird gerade\nbesonders geschützt”</td>\n</tr>\n<tr class=\"even\">\n<td>Hinweistext</td>\n<td>Erläuternder Text unter der Überschrift. Default: „Ihr Browser wird\nkurz geprüft — einen Moment bitte.”</td>\n</tr>\n<tr class=\"odd\">\n<td>NoScript-Hinweis</td>\n<td>Nur sichtbar bei deaktiviertem JS. Default: „Für die\nSicherheitsprüfung muss JavaScript aktiviert sein.”</td>\n</tr>\n<tr class=\"even\">\n<td>Hintergrundfarbe</td>\n<td>Hex, z. B. <code>#0a0a0a</code>. Default: <code>#f0f0f1</code></td>\n</tr>\n<tr class=\"odd\">\n<td>Textfarbe</td>\n<td>Hex, z. B. <code>#ffffff</code>. Default: <code>#1d2327</code></td>\n</tr>\n<tr class=\"even\">\n<td>Eigenes CSS</td>\n<td>Beliebige CSS-Regeln. Werden nach dem Default-Stylesheet ausgegeben\nund überschreiben alles. Verfügbare CSS-Variablen:\n<code>--creationell-captcha-ua-bg</code>,\n<code>--creationell-captcha-ua-text</code>. Verfügbare Selektoren:\n<code>body</code>, <code>.crea-ua</code>, <code>.crea-ua h1</code>,\n<code>.crea-ua p</code>, <code>.crea-ua noscript</code>,\n<code>.crea-ua-logo</code></td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"tab-analytics\">Tab: Analytics</h3>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Event-Log aktivieren</td>\n<td>Schreibt jede Aktion in die Tabelle\n<code>&lt;prefix&gt;creationell_captcha_events</code>. Aggregierte\nTageszähler laufen immer</td>\n</tr>\n<tr class=\"even\">\n<td>Aufbewahrungsdauer</td>\n<td>Tage, nach denen Event-Log-Einträge gelöscht werden (Default\n30)</td>\n</tr>\n<tr class=\"odd\">\n<td>IP-Adressen anonymisieren</td>\n<td>DSGVO-First: trunkiert IPv4 auf das letzte Oktett, IPv6 auf die\nletzten 80 Bit (Default: an)</td>\n</tr>\n<tr class=\"even\">\n<td>Request-Body-Fingerprint speichern</td>\n<td>JSON-Map aus Feldnamen und Wertlängen — ohne die Werte selbst.\nSensitive Feldnamen (<code>password</code>, <code>secret</code>,\n<code>token</code>, <code>iban</code>, <code>api_key</code>,\n<code>cvv</code>, …) werden zusätzlich gehasht</td>\n</tr>\n<tr class=\"odd\">\n<td>Erfolgreiche Verifikationen loggen</td>\n<td>Per-Event-Typ-Schalter, Default: an</td>\n</tr>\n<tr class=\"even\">\n<td>Fehlgeschlagene Verifikationen loggen</td>\n<td>Default: an</td>\n</tr>\n<tr class=\"odd\">\n<td>Firewall-Blocks loggen</td>\n<td>Default: an</td>\n</tr>\n<tr class=\"even\">\n<td>Rate-Limit-Blocks loggen</td>\n<td>Default: an</td>\n</tr>\n<tr class=\"odd\">\n<td>Under-Attack-Abfragen loggen</td>\n<td>Default: an</td>\n</tr>\n<tr class=\"even\">\n<td>Bestandene Under-Attack-Prüfungen loggen</td>\n<td>Default: an</td>\n</tr>\n<tr class=\"odd\">\n<td>Ausgestellte Challenges loggen</td>\n<td>Default: <strong>aus</strong> (hochvolumig)</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"tab-e-mail-schutz\">Tab: E-Mail-Schutz</h3>\n<table>\n<colgroup>\n<col style=\"width: 36%\" />\n<col style=\"width: 63%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Option</th>\n<th>Beschreibung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>E-Mail-Adressen verschleiern</td>\n<td>Master-Toggle</td>\n</tr>\n<tr class=\"even\">\n<td>Verschleierungsmodus</td>\n<td><code>content</code> (Filter auf <code>the_content</code> /\n<code>the_excerpt</code> / <code>widget_text</code> /\n<code>widget_block_content</code> / <code>comment_text</code>) oder\n<code>buffer</code> (Vollseiten-Ausgabepuffer)</td>\n</tr>\n</tbody>\n</table>\n<p>Im Buffer-Modus werden auch theme-hartkodierte\n<code>mailto:</code>-Links und Klartextadressen im Footer/Header\nerfasst. <code>&lt;head&gt;</code>, <code>&lt;script&gt;</code> und\n<code>&lt;style&gt;</code> bleiben unberührt. Feed-Requests und der\nAdmin-Bereich umgehen die Obfuskation immer.</p>\n<hr />\n<h2 id=\"shortcode-template-tag\">Shortcode &amp; Template-Tag</h2>\n<h3 id=\"creationell_captcha\"><code>[creationell_captcha]</code></h3>\n<p>Bettet das ALTCHA-Widget an beliebiger Stelle ein.</p>\n<table>\n<thead>\n<tr class=\"header\">\n<th>Attribut</th>\n<th>Werte</th>\n<th>Default</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>class</code></td>\n<td>CSS-Klassen</td>\n<td>—</td>\n</tr>\n</tbody>\n</table>\n<p>Bei aktiviertem CF7-Plugin ist <code>[creationell_captcha]</code>\nzusätzlich als CF7-Form-Tag verfügbar und kann direkt im CF7-Form-Editor\nplatziert werden.</p>\n<h3\nid=\"creationell_captcha_widget\"><code>creationell_captcha_widget()</code></h3>\n<p>Template-Tag mit identischer Wirkung. Nützlich, wenn ein Shortcode\nnicht in Frage kommt (z. B. in Theme-PHP-Templates):</p>\n<div class=\"sourceCode\" id=\"cb1\"><pre\nclass=\"sourceCode php\"><code class=\"sourceCode php\"><span id=\"cb1-1\"><a href=\"#cb1-1\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"op\">&lt;</span>form method<span class=\"op\">=</span><span class=\"st\">&quot;post&quot;</span><span class=\"op\">&gt;</span></span>\n<span id=\"cb1-2\"><a href=\"#cb1-2\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"op\">&lt;!--</span> … <span class=\"cn\">F</span>elder … <span class=\"op\">-</span>-&gt;</span>\n<span id=\"cb1-3\"><a href=\"#cb1-3\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"op\">&lt;</span><span class=\"ot\">?</span>php creationell_captcha_widget()<span class=\"ot\">;</span> <span class=\"kw\">?&gt;</span></span>\n<span id=\"cb1-4\"><a href=\"#cb1-4\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"op\">&lt;</span>button type<span class=\"op\">=</span><span class=\"st\">&quot;submit&quot;</span><span class=\"op\">&gt;</span><span class=\"cn\">S</span>enden<span class=\"op\">&lt;/</span>button<span class=\"op\">&gt;</span></span>\n<span id=\"cb1-5\"><a href=\"#cb1-5\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"op\">&lt;/</span>form<span class=\"op\">&gt;</span></span></code></pre></div>\n<p>Bei serverseitiger Verifikation immer auch den Pfad in\n<strong>Geschützte Pfade</strong> eintragen (siehe nächster Abschnitt) —\nsonst läuft eine manipulierte Submission ungeprüft durch.</p>\n<hr />\n<h2 id=\"geschützte-pfade-interceptor\">Geschützte Pfade &amp;\nInterceptor</h2>\n<p>Der Interceptor läuft auf <code>init</code> und ist die generische\nSchutzschicht für <strong>eigene</strong> Formulare. Konfiguriert wird\ner im Captcha-Tab.</p>\n<h3 id=\"pfad-muster\">Pfad-Muster</h3>\n<p><code>[creationell_captcha]</code>-Shortcode und Template-Tag rendern\nnur das Widget. Die Server-Verifikation übernimmt der Interceptor anhand\nder Pfad-Liste.</p>\n<pre><code>/kontakt              ← exakt\n/forms/*              ← Wildcard\n!/forms/whitelisted   ← Ausschluss (mit ! kombinierbar)</code></pre>\n<p><code>!</code>-Muster greifen vor positiven Mustern. So lässt sich\n<code>/forms/*</code> schützen, ein einzelner Sub-Pfad aber gezielt\nfreistellen.</p>\n<h3 id=\"action-schutz\">Action-Schutz</h3>\n<p>Für AJAX-/Admin-Post-Endpoints reicht die Pfad-Liste nicht — Requests\ngehen alle an <code>admin-ajax.php</code> oder\n<code>admin-post.php</code>. Die Liste <strong>Geschützte\nAktionen</strong> wertet stattdessen das <code>action</code>-Feld (POST\noder GET) aus:</p>\n<pre><code>my-custom-action\nform/*\n!form/internal</code></pre>\n<p>Action-Treffer überschreiben den <code>is_admin()</code>-Bypass — die\nVerifikation läuft auch dann, wenn der Aufruf aus dem Admin-Backend\nkäme.</p>\n<h3 id=\"auto-inject-auf-pfaden\">Auto-Inject auf Pfaden</h3>\n<p>Die <strong>Inject-Pfade</strong>-Liste fügt die Sicherheitsabfrage\nautomatisch vor jedem <code>&lt;/form&gt;</code> der passenden Seite\nein, ohne dass das Theme oder ein Plugin angepasst werden muss.\nIdempotent: Formulare mit bereits eingebautem Widget bleiben\nunangetastet.</p>\n<h3 id=\"bypass-kette\">Bypass-Kette</h3>\n<p>Vor jeder Verifikation läuft die Bypass-Kette in dieser\nReihenfolge:</p>\n<ol type=\"1\">\n<li>Kill-Switch <code>CREATIONELL_CAPTCHA_DISABLE</code>\n(wp-config-Konstante)</li>\n<li>Master-Toggle aus</li>\n<li>Request-Methode <code>GET</code> (Renderpfad — Verify nur auf\nPOST/PUT/DELETE/PATCH)</li>\n<li>CLI / Cron / XML-RPC (nicht-Browser-Kontexte)</li>\n<li><code>is_admin()</code> — <strong>wird durch Action-Schutz\nüberschrieben</strong>, sobald die <code>action</code> auf einer\ngeschützten Liste steht</li>\n<li>REST-API-Eigen-Endpoints (Challenge-/Code-Routes)</li>\n<li>WordPress-Kernformulare (siehe Tab Formulare)</li>\n<li><code>edit_posts</code>-Capability (eingeloggte User)</li>\n<li>Bei aktiviertem Toggle: alle eingeloggten User</li>\n<li>Globale Bypass-Quellen: IP-Allowlist, UA-Allowlist,\nCookie-Bypass</li>\n</ol>\n<p>Greift einer der Schritte, wird die Anfrage durchgelassen. Auf\nFormular-Ebene wird der erfolgreiche Bypass als\n<code>verified</code>-Event mit Grund-Annotation geloggt.</p>\n<h3 id=\"entwickler-filter\">Entwickler-Filter</h3>\n<div class=\"sourceCode\" id=\"cb4\"><pre\nclass=\"sourceCode php\"><code class=\"sourceCode php\"><span id=\"cb4-1\"><a href=\"#cb4-1\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"co\">// Pfad/Action-Listen runtime ergänzen</span></span>\n<span id=\"cb4-2\"><a href=\"#cb4-2\" aria-hidden=\"true\" tabindex=\"-1\"></a>add_filter( <span class=\"st\">&#39;creationell_captcha_interceptor_paths&#39;</span><span class=\"ot\">,</span> <span class=\"kw\">function</span> ( <span class=\"dt\">array</span> <span class=\"va\">$paths</span> )<span class=\"ot\">:</span> <span class=\"dt\">array</span> {</span>\n<span id=\"cb4-3\"><a href=\"#cb4-3\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"va\">$paths</span>[] <span class=\"op\">=</span> <span class=\"st\">&#39;/api/mein-form/*&#39;</span><span class=\"ot\">;</span></span>\n<span id=\"cb4-4\"><a href=\"#cb4-4\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"cf\">return</span> <span class=\"va\">$paths</span><span class=\"ot\">;</span></span>\n<span id=\"cb4-5\"><a href=\"#cb4-5\" aria-hidden=\"true\" tabindex=\"-1\"></a>} )<span class=\"ot\">;</span></span>\n<span id=\"cb4-6\"><a href=\"#cb4-6\" aria-hidden=\"true\" tabindex=\"-1\"></a></span>\n<span id=\"cb4-7\"><a href=\"#cb4-7\" aria-hidden=\"true\" tabindex=\"-1\"></a>add_filter( <span class=\"st\">&#39;creationell_captcha_interceptor_actions&#39;</span><span class=\"ot\">,</span> <span class=\"kw\">function</span> ( <span class=\"dt\">array</span> <span class=\"va\">$actions</span> )<span class=\"ot\">:</span> <span class=\"dt\">array</span> {</span>\n<span id=\"cb4-8\"><a href=\"#cb4-8\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"va\">$actions</span>[] <span class=\"op\">=</span> <span class=\"st\">&#39;mein_plugin_form&#39;</span><span class=\"ot\">;</span></span>\n<span id=\"cb4-9\"><a href=\"#cb4-9\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"cf\">return</span> <span class=\"va\">$actions</span><span class=\"ot\">;</span></span>\n<span id=\"cb4-10\"><a href=\"#cb4-10\" aria-hidden=\"true\" tabindex=\"-1\"></a>} )<span class=\"ot\">;</span></span>\n<span id=\"cb4-11\"><a href=\"#cb4-11\" aria-hidden=\"true\" tabindex=\"-1\"></a></span>\n<span id=\"cb4-12\"><a href=\"#cb4-12\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"co\">// Eigenen Bypass anhängen (true = durchlassen)</span></span>\n<span id=\"cb4-13\"><a href=\"#cb4-13\" aria-hidden=\"true\" tabindex=\"-1\"></a>add_filter( <span class=\"st\">&#39;creationell_captcha_interceptor_bypass&#39;</span><span class=\"ot\">,</span> <span class=\"kw\">function</span> ( <span class=\"dt\">bool</span> <span class=\"va\">$bypass</span> )<span class=\"ot\">:</span> <span class=\"dt\">bool</span> {</span>\n<span id=\"cb4-14\"><a href=\"#cb4-14\" aria-hidden=\"true\" tabindex=\"-1\"></a>    <span class=\"cf\">return</span> <span class=\"va\">$bypass</span> <span class=\"op\">||</span> ( <span class=\"fu\">defined</span>( <span class=\"st\">&#39;MY_DEV_BYPASS&#39;</span> ) <span class=\"op\">&amp;&amp;</span> <span class=\"cn\">MY_DEV_BYPASS</span> )<span class=\"ot\">;</span></span>\n<span id=\"cb4-15\"><a href=\"#cb4-15\" aria-hidden=\"true\" tabindex=\"-1\"></a>} )<span class=\"ot\">;</span></span>\n<span id=\"cb4-16\"><a href=\"#cb4-16\" aria-hidden=\"true\" tabindex=\"-1\"></a></span>\n<span id=\"cb4-17\"><a href=\"#cb4-17\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"co\">// Custom geschützten Pfad zur Laufzeit registrieren</span></span>\n<span id=\"cb4-18\"><a href=\"#cb4-18\" aria-hidden=\"true\" tabindex=\"-1\"></a>creationell_captcha_protect_path( <span class=\"st\">&#39;/checkout/step2&#39;</span> )<span class=\"ot\">;</span></span></code></pre></div>\n<hr />\n<h2 id=\"bild-code-challenge\">Bild-Code-Challenge</h2>\n<p>Die Bild-Code-Challenge ist eine <strong>zweite Stufe</strong> nach\nder PoW-Verifikation — kein Ersatz. Der Browser löst zuerst die PoW, der\nServer schickt dann optional ein PNG mit einem 4–8-stelligen Code, den\nder Nutzer abtippt.</p>\n<h3 id=\"trigger-bedingungen\">Trigger-Bedingungen</h3>\n<table>\n<colgroup>\n<col style=\"width: 50%\" />\n<col style=\"width: 50%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Trigger</th>\n<th>Wirkung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Immer</td>\n<td>Pauschal aktiv bei jedem Captcha-Request</td>\n</tr>\n<tr class=\"even\">\n<td>Under-Attack-Modus</td>\n<td>Greift nur, wenn UA-Modus aktiv ist (außer auf dem Interstitial —\ndort unterdrückt)</td>\n</tr>\n<tr class=\"odd\">\n<td>Rate-Limit-Schwelle</td>\n<td>Greift ab konfigurierter Auslastung (50–95 %) der IP-Bucket</td>\n</tr>\n<tr class=\"even\">\n<td>Watch-Liste</td>\n<td>IPs/CIDRs, die immer eine Code-Challenge bekommen</td>\n</tr>\n</tbody>\n</table>\n<p>Mehrere Trigger sind OR-verknüpft.</p>\n<h3 id=\"rest-endpoints\">REST-Endpoints</h3>\n<table>\n<colgroup>\n<col style=\"width: 39%\" />\n<col style=\"width: 30%\" />\n<col style=\"width: 30%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Methode</th>\n<th>Route</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>GET</code></td>\n<td><code>/wp-json/creationell-captcha/v1/code-image?t=&lt;token&gt;</code></td>\n<td>PNG-Bild ausliefern (Cache-Header <code>no-store</code>)</td>\n</tr>\n<tr class=\"even\">\n<td><code>POST</code></td>\n<td><code>/wp-json/creationell-captcha/v1/code-verify</code></td>\n<td>Code prüfen, signierte ALTCHA-Payload zurückgeben</td>\n</tr>\n</tbody>\n</table>\n<p>Tokens sind opake 32-Hex-Server-Identifier; der erwartete Code lebt\nnur in einem WP-Transient und verlässt den Server nie. Die\nzurückgegebene Payload geht durch den bestehenden Verify-Pfad.</p>\n<h3 id=\"rendering\">Rendering</h3>\n<p>PHP-GD mit vendorierter DejaVuSans-Bold-TTF\n(<code>assets/fonts/captcha.ttf</code>) und naiver Anti-OCR-Verzerrung\n(rotierte Zeichen, Querlinien, Rauschen). Fehlt die TTF, fällt der\nRenderer auf den GD-Bitmap-Font 5 zurück.</p>\n<p>Fehlt <strong>GD selbst</strong>, deaktiviert sich das Feature\nstillschweigend und der Section-Renderer zeigt eine Warn-Notice.</p>\n<h3 id=\"bypass-schutz\">Bypass-Schutz</h3>\n<p><code>Engine::verify()</code> lehnt jeden Payload ab, in dem\n<code>parameters.data.ccode</code> clientseitig gesetzt ist — ein\nAngreifer kann den originalen Payload nicht recyclen, um die Code-Stufe\nzu überspringen.</p>\n<hr />\n<h2 id=\"under-attack-modus\">Under-Attack-Modus</h2>\n<p>Der Under-Attack-Modus ist ein <strong>Notfall-Schalter</strong> für\naktive Bot-Wellen. Bei aktivem Modus liefert WordPress für jeden\nanonymen Besucher ein HTTP-503-Interstitial mit einem invisiblen\nALTCHA-Widget aus. Erst nach bestandener PoW-Sicherheitsabfrage setzt\nder Server ein HMAC-signiertes Pass-Cookie und lässt den Browser auf die\neigentliche Seite.</p>\n<h3 id=\"ablauf\">Ablauf</h3>\n<ol type=\"1\">\n<li>Anonymer Besucher öffnet beliebige Seite</li>\n<li><code>template_redirect</code> fängt den Request ab, zeigt das\nInterstitial</li>\n<li>Browser löst die PoW-Sicherheitsabfrage im Hintergrund</li>\n<li>Server prüft, signiert das Pass-Cookie\n<code>creationell_captcha_ua_pass</code> (HMAC, gültig für die\nkonfigurierte Pass-Dauer)</li>\n<li>Browser wird mit <code>Location</code>-Header auf die ursprüngliche\nURL umgeleitet</li>\n<li>Folgende Requests passieren den Modus, bis das Cookie abläuft</li>\n</ol>\n<p><code>wp-admin</code>, REST-API und Cron sind automatisch ausgenommen\n— die Site bleibt von innen administrierbar. Eingeloggte User sind per\nDefault ebenfalls ausgenommen.</p>\n<h3 id=\"kill-switch\">Kill-Switch</h3>\n<p>Definiert man\n<code>define( 'CREATIONELL_CAPTCHA_DISABLE', true );</code> in\n<code>wp-config.php</code>, sind alle CreaCaptcha-Funktionen — inklusive\nUnder-Attack — global deaktiviert. Praktisch für den Fall, dass die Site\nsich selbst aussperrt.</p>\n<hr />\n<h2 id=\"statistik-event-log\">Statistik &amp; Event-Log</h2>\n<h3 id=\"aggregat-statistiken\">Aggregat-Statistiken</h3>\n<p>Immer aktiv, datenschutzfreundlich, keine personenbezogenen Daten.\nZwei Counter-Tabellen in <code>wp_options</code>:</p>\n<ul>\n<li><code>creationell_captcha_analytics</code> — Tageszähler je\nEreignistyp</li>\n<li><code>creationell_captcha_analytics_hourly</code> — Stundenzähler je\nEreignistyp (für die 24-h-Sicht)</li>\n</ul>\n<h3 id=\"detail-event-log\">Detail-Event-Log</h3>\n<p>Optional, schaltbar im Analytics-Tab. Schreibt in die eigene Tabelle\n<code>&lt;prefix&gt;creationell_captcha_events</code> mit 15\nSpalten:</p>\n<table>\n<colgroup>\n<col style=\"width: 50%\" />\n<col style=\"width: 50%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Spalte</th>\n<th>Inhalt</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>id</code></td>\n<td>Auto-Increment</td>\n</tr>\n<tr class=\"even\">\n<td><code>event_type</code></td>\n<td><code>verified</code> / <code>failed</code> / <code>firewall</code>\n/ <code>ratelimit</code> / <code>underattack</code> /\n<code>underattack_passed</code> / <code>challenge</code></td>\n</tr>\n<tr class=\"odd\">\n<td><code>created_at</code></td>\n<td>UTC-Zeitstempel</td>\n</tr>\n<tr class=\"even\">\n<td><code>ip</code></td>\n<td>Client-IP (anonymisiert, wenn konfiguriert)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>path</code></td>\n<td>Request-Pfad (REQUEST_URI ohne Query-Args — keine GET-Token im\nLog)</td>\n</tr>\n<tr class=\"even\">\n<td><code>user_id</code></td>\n<td>WordPress-User-ID (falls eingeloggt)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>user_agent</code></td>\n<td>UA-String</td>\n</tr>\n<tr class=\"even\">\n<td><code>referrer</code></td>\n<td>HTTP-Referer</td>\n</tr>\n<tr class=\"odd\">\n<td><code>plugin</code></td>\n<td>Auslösendes Modul (<code>cf7</code> / <code>forminator</code> /\n<code>wpforms</code> / <code>wc-checkout</code> / …)</td>\n</tr>\n<tr class=\"even\">\n<td><code>action</code></td>\n<td>Action-Name (bei admin-post/admin-ajax)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>form_id</code></td>\n<td>Plugin-spezifische Form-ID (z. B. WPForms-/Forminator-ID)</td>\n</tr>\n<tr class=\"even\">\n<td><code>interceptor</code></td>\n<td>Interceptor-Pfadmuster, das gegriffen hat</td>\n</tr>\n<tr class=\"odd\">\n<td><code>reason</code></td>\n<td>Klartext-Grund (z. B. „IP-Allowlist”, „Replay-Schutz”, „PoW-Hash\nfalsch”)</td>\n</tr>\n<tr class=\"even\">\n<td><code>verification_data</code></td>\n<td>Eingereichter Captcha-Payload (gekürzt)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>request_body</code></td>\n<td>Body-Fingerprint (JSON-Map Feldname → Wertlänge; sensitive Felder\ngehasht)</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"statistik-dashboard\">Statistik-Dashboard</h3>\n<p><strong>CreaCaptcha → Statistik</strong> liefert drei Tabs:</p>\n<table>\n<colgroup>\n<col style=\"width: 38%\" />\n<col style=\"width: 61%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Tab</th>\n<th>Inhalt</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Übersicht</td>\n<td>Vier KPI-Kacheln für die letzten 24 h (Captcha gelöst, Abgewehrt =\nFirewall + Rate-Limit, Under-Attack Abfragen/bestanden, Captcha\nfehlgeschlagen) plus thematisch gruppierte Vergleichstabellen\n(Formular-Captchas / Abgewehrte Zugriffe / Under-Attack-Modus /\nTechnisch) über vier Zeitfenster (24 h / 7 Tage / 30 Tage / 90\nTage)</td>\n</tr>\n<tr class=\"even\">\n<td>Verlauf</td>\n<td>Zeitreihen-Plot je Ereignistyp über das gewählte Fenster</td>\n</tr>\n<tr class=\"odd\">\n<td>Ereignisse</td>\n<td>Filterbare Tabelle der Detail-Events, seitenweise (50/Seite), mit\nDetail-Modal je Eintrag und CSV-Export der gefilterten Menge</td>\n</tr>\n</tbody>\n</table>\n<p>Die Filter-Leiste im Ereignisse-Tab kombiniert Freitextsuche (IP +\nPfad), Ereignistyp-Filter und Von/Bis-Datumsbereich.</p>\n<h3 id=\"performance\">Performance</h3>\n<p>Seit v0.26.0:</p>\n<ul>\n<li><code>Analytics::record()</code> sammelt Counter-Deltas in\nClass-Statics und flusht sie auf <code>shutdown</code> in einem einzigen\n<code>get_option</code>/<code>update_option</code>-Paar je\nCounter-Tabelle — statt zwei Roundtrips pro Event</li>\n<li>Composite-Index\n<code>event_type_created (event_type, created_at)</code> auf der\nEvents-Tabelle: typgefilterte Range-Queries laufen als reiner\nIndex-Range-Scan ohne Filesort</li>\n<li><code>creationell_captcha_get_settings()</code> cacht das\nDefault-Merge-Ergebnis pro Request</li>\n</ul>\n<hr />\n<h2 id=\"e-mail-schutz-obfuskation\">E-Mail-Schutz (Obfuskation)</h2>\n<h3 id=\"zwei-modi\">Zwei Modi</h3>\n<table>\n<colgroup>\n<col style=\"width: 43%\" />\n<col style=\"width: 56%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Modus</th>\n<th>Wirkung</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Content</td>\n<td><code>the_content</code>, <code>the_excerpt</code>,\n<code>widget_text</code>, <code>widget_block_content</code>,\n<code>comment_text</code> durchlaufen\n<code>EmailObfuscator::process()</code></td>\n</tr>\n<tr class=\"even\">\n<td>Buffer</td>\n<td>Ganzseiten-<code>ob_start()</code> auf\n<code>template_redirect</code> —\n<code>EmailObfuscator::process_page()</code> verarbeitet den gesamten\n<code>&lt;body&gt;</code></td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"verschleierung\">Verschleierung</h3>\n<p><code>mailto:</code>-Hrefs werden zu\n<code>href=\"#\" data-cce=\"&lt;hex&gt;\"</code>, Klartext-Adressen zu\n<code>&lt;span data-cce=\"&lt;hex&gt;\"&gt;[E-Mail-Adresse — bitte JavaScript aktivieren]&lt;/span&gt;</code>.\nDer Hex-String ist eine XOR-Verschlüsselung der Adresse mit einem\neinmaligen Per-Page-Key.</p>\n<h3 id=\"decoder\">Decoder</h3>\n<p><code>assets/js/email-obfuscation.js</code> läuft auf\n<code>DOMContentLoaded</code>, bindet sich auf alle\n<code>[data-cce]</code>-Elemente und stellt die Original-Adresse im\nBrowser wieder her.</p>\n<h3 id=\"ausnahmen\">Ausnahmen</h3>\n<p><code>&lt;head&gt;</code>, <code>&lt;script&gt;</code>,\n<code>&lt;style&gt;</code> werden im Buffer-Modus übersprungen.\nFeed-Requests, <code>wp-admin</code> und der Kill-Switch umgehen die\nObfuskation immer.</p>\n<hr />\n<h2 id=\"wp-cli\">WP-CLI</h2>\n<p>Alle Plugin-Funktionen sind per <code>wp creacaptcha</code>\nautomatisierbar. Eine Übersicht aller Befehle:</p>\n<pre><code>wp help creacaptcha</code></pre>\n<h3 id=\"betriebsbefehle\">Betriebsbefehle</h3>\n<table>\n<colgroup>\n<col style=\"width: 53%\" />\n<col style=\"width: 46%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Befehl</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>wp creacaptcha status</code></td>\n<td>Übersicht: Kill-Switch, Module, Listengrößen, Proxy/CF-Trust,\nCode-Challenge, Watchlist, Form-Plugin-Toggles</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha info</code></td>\n<td>Diagnose: Plugin-Version, Lib-Version, Algorithmus, HMAC-Secrets\nvorhanden, Event-Log-Tabelle</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha stats [--window=24h\\|7d\\|30d\\|90d\\|all]</code></td>\n<td>Analytics-Kennzahlen für das gewählte Fenster</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha enable &lt;feature&gt;</code></td>\n<td>Modul/Feature aktivieren (siehe unten)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha disable &lt;feature&gt;</code></td>\n<td>Modul/Feature deaktivieren</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha repair</code></td>\n<td>Selbstheilung: fehlende Secrets generieren, Event-Log-Tabelle\nanlegen, Default-Keys ergänzen</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha doctor</code></td>\n<td>Pflicht-Checks: Lib, Secrets, Tabelle, Cron, Konflikte,\nPHP-/GD-/Sodium-Versionen, Settings-Defaults</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha test-bypass [--ip=…] [--ua=…] [--cookie=…]</code></td>\n<td>Simuliert die Bypass-Auswertung; Exit 0 bei Bypass, Exit 1\nsonst</td>\n</tr>\n</tbody>\n</table>\n<p>Die <code>&lt;feature&gt;</code>-Schlüssel für\n<code>enable</code>/<code>disable</code>: <code>captcha</code>,\n<code>comments</code>, <code>login</code>, <code>registration</code>,\n<code>password-reset</code>, <code>cf7</code>, <code>forminator</code>,\n<code>wpforms</code>, <code>woocommerce</code>,\n<code>wc-checkout</code>, <code>wc-login</code>,\n<code>wc-registration</code>, <code>wc-lost-password</code>,\n<code>firewall</code>, <code>ratelimit</code>,\n<code>under-attack</code>, <code>analytics</code>,\n<code>event-log</code>, <code>email-obfuscation</code>,\n<code>code-challenge</code>.</p>\n<h3 id=\"einstellungen\">Einstellungen</h3>\n<table>\n<colgroup>\n<col style=\"width: 53%\" />\n<col style=\"width: 46%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Befehl</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>wp creacaptcha settings list</code></td>\n<td>Alle Settings mit aktuellen Werten ausgeben</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha settings get &lt;key&gt;</code></td>\n<td>Einen Wert lesen</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha settings set &lt;key&gt; &lt;value&gt;</code></td>\n<td>Einen Wert setzen (bool / int / text / color / textblock / list /\njson)</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha settings export [--file=…]</code></td>\n<td>JSON-Export aller Settings</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha settings import --file=…</code></td>\n<td>JSON-Import</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha settings reset</code></td>\n<td>Voller Werksreset inklusive aller Listen</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha settings load-defaults</code></td>\n<td>Nur Konfigwerte zurücksetzen, Listen bleiben</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"listen-pflege\">Listen-Pflege</h3>\n<p>Jede Liste hat denselben Subcommand-Baukasten:\n<code>add &lt;eintrag&gt;</code>, <code>remove &lt;eintrag&gt;</code>,\n<code>list</code>, <code>clear</code>.</p>\n<table>\n<thead>\n<tr class=\"header\">\n<th>Befehl</th>\n<th>Liste</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>wp creacaptcha blocklist …</code></td>\n<td>IP-Blockliste</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha allowlist …</code></td>\n<td>IP-Erlaubnisliste (global wirksam)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha ua-blocklist …</code></td>\n<td>User-Agent-Blockliste</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha paths …</code></td>\n<td>Geschützte Pfade</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha actions …</code></td>\n<td>Geschützte Aktionen</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha inject-paths …</code></td>\n<td>Inject-Pfade</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha trusted-proxies …</code></td>\n<td>Vertrauenswürdige Proxies</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha bypass-ua …</code></td>\n<td>UA-Bypass-Liste</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha bypass-cookies …</code></td>\n<td>Cookie-Bypass (<code>name=wert</code>)</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha watchlist …</code></td>\n<td>Code-Challenge-Watchlist</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"cloudflare-cache\">Cloudflare-Cache</h3>\n<table>\n<colgroup>\n<col style=\"width: 53%\" />\n<col style=\"width: 46%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Befehl</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>wp creacaptcha cloudflare refresh</code></td>\n<td>CF-v4/v6-Ranges aktualisieren</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha cloudflare status</code></td>\n<td>Status des CF-Caches (Anzahl Ranges, letzter Refresh, nächster Cron,\nQuelle)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha cloudflare clear</code></td>\n<td>CF-Cache leeren</td>\n</tr>\n</tbody>\n</table>\n<p>Der frühere Alias <code>wp creacaptcha refresh-cloudflare-ips</code>\nwurde mit v1.0.1 entfernt — bitte\n<code>wp creacaptcha cloudflare refresh</code> verwenden.</p>\n<h3 id=\"event-log\">Event-Log</h3>\n<table>\n<colgroup>\n<col style=\"width: 53%\" />\n<col style=\"width: 46%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Befehl</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>wp creacaptcha log list [--fields=…] [--format=…] [--limit=…]</code></td>\n<td>Event-Log-Einträge auflisten; ohne <code>--fields</code>\n4-Spalten-Default, mit <code>--fields=</code> alle 15 Spalten\nverfügbar</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha log show &lt;id&gt;</code></td>\n<td>Einen Event mit allen 15 Spalten anzeigen</td>\n</tr>\n<tr class=\"odd\">\n<td><code>wp creacaptcha log clear</code></td>\n<td>Event-Log komplett leeren</td>\n</tr>\n<tr class=\"even\">\n<td><code>wp creacaptcha log prune</code></td>\n<td>Alte Einträge gemäß Aufbewahrungsdauer löschen</td>\n</tr>\n</tbody>\n</table>\n<p>Die Werkzeuge-Seite im Backend (siehe nächster Abschnitt) bietet\ndieselben Export-/Import-/Reset-/Load-Defaults-Aktionen.</p>\n<hr />\n<h2 id=\"werkzeuge\">Werkzeuge</h2>\n<p><strong>CreaCaptcha → Werkzeuge</strong> ist die Backend-Entsprechung\nder wichtigsten CLI-Aktionen. Fünf Karten:</p>\n<table>\n<colgroup>\n<col style=\"width: 46%\" />\n<col style=\"width: 53%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Karte</th>\n<th>Aktion</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td>Einstellungen exportieren</td>\n<td>Lädt alle Settings als JSON-Datei herunter</td>\n</tr>\n<tr class=\"even\">\n<td>Einstellungen importieren</td>\n<td>JSON-Upload, Validierung gegen das Settings-Schema</td>\n</tr>\n<tr class=\"odd\">\n<td>Standardwerte laden</td>\n<td>Konfigwerte auf Default zurücksetzen; <strong>Listen bleiben\nunverändert</strong></td>\n</tr>\n<tr class=\"even\">\n<td>Auf Werkseinstellungen zurücksetzen</td>\n<td>Voller Werksreset inklusive aller Listen (mit Warn-Box und\nConfirm-Dialog)</td>\n</tr>\n<tr class=\"odd\">\n<td>Cloudflare-IP-Cache</td>\n<td>Status + Buttons „Jetzt aktualisieren” und „Cache leeren”</td>\n</tr>\n</tbody>\n</table>\n<hr />\n<h2 id=\"developer-reference\">Developer Reference</h2>\n<p>Die wichtigsten Konstanten, Hooks und Filter im Überblick:</p>\n<h3 id=\"konstanten-wp-config.php-überschreibbar\">Konstanten\n(wp-config.php überschreibbar)</h3>\n<table>\n<colgroup>\n<col style=\"width: 40%\" />\n<col style=\"width: 33%\" />\n<col style=\"width: 25%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Konstante</th>\n<th>Default</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>CREATIONELL_CAPTCHA_VERSION</code></td>\n<td><code>'1.0.1'</code></td>\n<td>Plugin-Version</td>\n</tr>\n<tr class=\"even\">\n<td><code>CREATIONELL_CAPTCHA_FILE</code></td>\n<td><code>__FILE__</code></td>\n<td>Plugin-Hauptdatei</td>\n</tr>\n<tr class=\"odd\">\n<td><code>CREATIONELL_CAPTCHA_PLUGIN_PATH</code></td>\n<td><code>plugin_dir_path(...)</code></td>\n<td>Plugin-Ordner</td>\n</tr>\n<tr class=\"even\">\n<td><code>CREATIONELL_CAPTCHA_PLUGIN_URL</code></td>\n<td><code>plugin_dir_url(...)</code></td>\n<td>Plugin-URL</td>\n</tr>\n<tr class=\"odd\">\n<td><code>CREATIONELL_CAPTCHA_MIN_PHP</code></td>\n<td><code>'8.3'</code></td>\n<td>PHP-Mindestversion</td>\n</tr>\n<tr class=\"even\">\n<td><code>CREATIONELL_CAPTCHA_MIN_WP</code></td>\n<td><code>'6.9'</code></td>\n<td>WordPress-Mindestversion</td>\n</tr>\n<tr class=\"odd\">\n<td><code>CREATIONELL_CAPTCHA_DEBUG</code></td>\n<td><code>WP_DEBUG</code></td>\n<td>Aktiviert Debug-Logging</td>\n</tr>\n<tr class=\"even\">\n<td><code>CREATIONELL_CAPTCHA_DISABLE</code></td>\n<td><em>ungesetzt</em></td>\n<td>Wenn <code>true</code>: globaler Kill-Switch — alle Module aus</td>\n</tr>\n<tr class=\"odd\">\n<td><code>CREATIONELL_CAPTCHA_HMAC_SECRET</code></td>\n<td><em>autogeneriert</em></td>\n<td>Override für das Challenge-HMAC-Secret</td>\n</tr>\n<tr class=\"even\">\n<td><code>CREATIONELL_CAPTCHA_HMAC_KEY_SECRET</code></td>\n<td><em>autogeneriert</em></td>\n<td>Override für das HMAC-Key-Secret</td>\n</tr>\n<tr class=\"odd\">\n<td><code>CREATIONELL_CAPTCHA_TRUSTED_PROXIES</code></td>\n<td><em>ungesetzt</em></td>\n<td>Array von zusätzlich vertrauenswürdigen Proxy-CIDRs</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"hooks-actions\">Hooks (Actions)</h3>\n<table>\n<colgroup>\n<col style=\"width: 50%\" />\n<col style=\"width: 50%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Hook</th>\n<th>Wann</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>creationell_captcha_loaded</code></td>\n<td>Nach dem Plugin-Bootstrap, alle Module geladen</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_deactivated</code></td>\n<td>Beim Deaktivieren des Plugins</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_event</code></td>\n<td>Bei jedem Aggregat-Event-Bump (<code>$type</code>,\n<code>$context</code>)</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_firewall_blocked</code></td>\n<td>Firewall hat eine IP/UA geblockt</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_ratelimit_exceeded</code></td>\n<td>Rate-Limit für eine IP überschritten</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_interceptor_blocked</code></td>\n<td>Interceptor hat eine Submission abgewiesen</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_interceptor_passed</code></td>\n<td>Interceptor hat eine Submission durchgelassen</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"hooks-filter\">Hooks (Filter)</h3>\n<table>\n<colgroup>\n<col style=\"width: 53%\" />\n<col style=\"width: 46%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Filter</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>creationell_captcha_interceptor_paths</code></td>\n<td>Pfad-Liste runtime modifizieren</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_interceptor_actions</code></td>\n<td>Action-Liste runtime modifizieren</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_interceptor_bypass</code></td>\n<td>Eigene Bypass-Logik anhängen (<code>true</code> = durchlassen)</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_interceptor_guarded</code></td>\n<td>Modifiziert die Liste der „immer geschützten” Anker-Pfade</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_firewall_block</code></td>\n<td>Eigene Block-Logik anhängen (<code>true</code> = blocken)</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_forminator_autoinject</code></td>\n<td>Forminator-Autoinject je Formular toggeln (<code>bool</code>,\n<code>int $form_id</code>)</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_wpforms_autoinject</code></td>\n<td>WPForms-Autoinject je Formular toggeln</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_wc_checkout_autoinject</code></td>\n<td>WooCommerce-Checkout-Autoinject toggeln</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_wc_login_autoinject</code></td>\n<td>WooCommerce-Login-Autoinject toggeln</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_wc_registration_autoinject</code></td>\n<td>WooCommerce-Registrierungs-Autoinject toggeln</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_wc_lost_password_autoinject</code></td>\n<td>WooCommerce-Lost-Password-Autoinject toggeln</td>\n</tr>\n<tr class=\"even\">\n<td><code>creationell_captcha_request_body_sensitive_patterns</code></td>\n<td>Sensitive Feldnamen-Patterns für die Body-Fingerprint-Maskierung\nerweitern</td>\n</tr>\n<tr class=\"odd\">\n<td><code>creationell_captcha_doctor_checks</code></td>\n<td>Eigene Doctor-Checks zur WP-CLI-Diagnose ergänzen</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"rest-endpoints-1\">REST-Endpoints</h3>\n<p>Alle Routes unter dem Namespace\n<code>creationell-captcha/v1</code>:</p>\n<table>\n<colgroup>\n<col style=\"width: 39%\" />\n<col style=\"width: 30%\" />\n<col style=\"width: 30%\" />\n</colgroup>\n<thead>\n<tr class=\"header\">\n<th>Methode</th>\n<th>Route</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"odd\">\n<td><code>GET</code></td>\n<td><code>/challenge</code></td>\n<td>Neue PoW-Challenge ausstellen</td>\n</tr>\n<tr class=\"even\">\n<td><code>GET</code></td>\n<td><code>/code-image?t=&lt;token&gt;</code></td>\n<td>PNG der Bild-Code-Challenge ausliefern</td>\n</tr>\n<tr class=\"odd\">\n<td><code>POST</code></td>\n<td><code>/code-verify</code></td>\n<td>Eingegebenen Code prüfen, signierte ALTCHA-Payload zurückgeben</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"wichtige-php-helper\">Wichtige PHP-Helper</h3>\n<div class=\"sourceCode\" id=\"cb6\"><pre\nclass=\"sourceCode php\"><code class=\"sourceCode php\"><span id=\"cb6-1\"><a href=\"#cb6-1\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"co\">// Schutz für eigene Pfade registrieren</span></span>\n<span id=\"cb6-2\"><a href=\"#cb6-2\" aria-hidden=\"true\" tabindex=\"-1\"></a>creationell_captcha_protect_path( <span class=\"st\">&#39;/checkout/step2&#39;</span> )<span class=\"ot\">;</span></span>\n<span id=\"cb6-3\"><a href=\"#cb6-3\" aria-hidden=\"true\" tabindex=\"-1\"></a></span>\n<span id=\"cb6-4\"><a href=\"#cb6-4\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"co\">// Widget rendern (Template-Tag-Variante)</span></span>\n<span id=\"cb6-5\"><a href=\"#cb6-5\" aria-hidden=\"true\" tabindex=\"-1\"></a>creationell_captcha_widget()<span class=\"ot\">;</span></span>\n<span id=\"cb6-6\"><a href=\"#cb6-6\" aria-hidden=\"true\" tabindex=\"-1\"></a></span>\n<span id=\"cb6-7\"><a href=\"#cb6-7\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"co\">// Settings memoiziert laden</span></span>\n<span id=\"cb6-8\"><a href=\"#cb6-8\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"va\">$settings</span> <span class=\"op\">=</span> creationell_captcha_get_settings()<span class=\"ot\">;</span></span>\n<span id=\"cb6-9\"><a href=\"#cb6-9\" aria-hidden=\"true\" tabindex=\"-1\"></a></span>\n<span id=\"cb6-10\"><a href=\"#cb6-10\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"co\">// Bypass-Auswertung manuell aufrufen</span></span>\n<span id=\"cb6-11\"><a href=\"#cb6-11\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"va\">$bypass_active</span> <span class=\"op\">=</span> creationell_captcha_request_bypassed()<span class=\"ot\">;</span></span></code></pre></div>\n<h3 id=\"architektur\">Architektur</h3>\n<p>Das Plugin folgt einer require-basierten\nClassic-WordPress-Architektur. Die Klassen liegen unter\n<code>Creationell\\Captcha\\…</code> in <code>includes/class-*.php</code>;\nprozedurale Bootstrap-Helper in <code>includes/&lt;modul&gt;.php</code>.\nDie geprefixte ALTCHA-Library landet via Strauss in\n<code>lib/Creationell\\Captcha\\Vendor\\…</code>. Es gibt\n<strong>keinen</strong> Composer-Autoloader im Release-ZIP — alle\nRequires sind explizit.</p>\n<hr />\n<h2 id=\"faq\">FAQ</h2>\n<h3 id=\"sendet-creacaptcha-daten-an-externe-dienste\">Sendet CreaCaptcha\nDaten an externe Dienste?</h3>\n<p>Nein. Das Plugin arbeitet vollständig selbst-gehostet — es gibt keine\nAPI-Aufrufe, kein Telemetrie-Backend, keinen Lizenz-Check und keine\nSaaS-Anbindung. Die einzige optionale externe Anfrage ist der\nCloudflare-IP-Refresh aus den offiziellen Cloudflare-Listen, der\nausschließlich auf expliziten Toggle läuft.</p>\n<h3 id=\"welcher-captcha-algorithmus-läuft-im-hintergrund\">Welcher\nCaptcha-Algorithmus läuft im Hintergrund?</h3>\n<p>CreaCaptcha nutzt die offizielle MIT-Bibliothek\n<code>altcha-org/altcha</code>. Standardmäßig kommt PBKDF2/SHA-256 zum\nEinsatz (kein PHP-Extension-Bedarf). Optional lässt sich auf Argon2id\numschalten, dafür wird <code>ext-sodium</code> benötigt.</p>\n<h3 id=\"funktioniert-das-plugin-ohne-javascript\">Funktioniert das Plugin\nohne JavaScript?</h3>\n<p>Nein — die Proof-of-Work-Sicherheitsabfrage muss vom Browser gelöst\nwerden. Ohne JavaScript erscheint das Widget als Hinweistext, und die\nServer-Verifikation wird die Submission abweisen. Für ein vollständig\nJS-loses Schutz-Setup ist die Firewall+Rate-Limit-Schicht der richtige\nAnsatz.</p>\n<h3 id=\"welche-form-plugins-werden-unterstützt\">Welche Form-Plugins\nwerden unterstützt?</h3>\n<p>Mit dedizierten Integrationen: <strong>Contact Form 7</strong>,\n<strong>Forminator</strong>, <strong>WPForms</strong> (Lite und Pro),\n<strong>WooCommerce</strong> (Checkout, My-Account-Login, Registrierung,\nLost-Password). Beliebige andere Formulare lassen sich über\n<code>[creationell_captcha]</code> und die Geschützte-Pfade-Liste\nabsichern. Für AJAX-/Admin-Post-Endpoints gibt es zusätzlich die\nGeschützte-Aktionen-Liste.</p>\n<h3\nid=\"wie-schütze-ich-ein-eigenes-formular-auf-einer-beliebigen-seite\">Wie\nschütze ich ein eigenes Formular auf einer beliebigen Seite?</h3>\n<p>Drei Schritte: (1) Den Shortcode <code>[creationell_captcha]</code>\noder das Template-Tag <code>creationell_captcha_widget()</code> ins\nFormular einbauen. (2) Den Pfad der Seite oder den Submit-Pfad in\n<strong>Captcha → Interceptor → Geschützte Pfade</strong> eintragen. (3)\nBei AJAX-/Admin-Post-Submissions zusätzlich den\n<code>action</code>-Namen in <strong>Geschützte Aktionen</strong>. Der\nInterceptor verifiziert dann automatisch jede Submission.</p>\n<h3 id=\"was-passiert-mit-ungelösten-bot-submissions\">Was passiert mit\nungelösten Bot-Submissions?</h3>\n<p>Der Server lehnt die Submission ab. Bei klassischen Formularen erhält\nder Browser die normale Validierungs-Fehlermeldung des jeweiligen\nPlugins. Bei AJAX wird <code>403 Forbidden</code> mit JSON-Body\ngeliefert. Der Bot bekommt keine Hilfe in Form von Hinweisen, woran das\nCaptcha gescheitert ist — der <code>reason</code> landet nur im\nEvent-Log.</p>\n<h3\nid=\"wie-kann-ich-mich-selbst-aussperren-und-wie-komme-ich-wieder-rein\">Wie\nkann ich mich selbst aussperren — und wie komme ich wieder rein?</h3>\n<p>Wer durch eigene Firewall-Regeln, Rate-Limit oder einen kaputten\nUnder-Attack-Modus ausgesperrt wird, kann zu jeder Zeit per\n<code>wp-config.php</code> den Kill-Switch setzen:</p>\n<div class=\"sourceCode\" id=\"cb7\"><pre\nclass=\"sourceCode php\"><code class=\"sourceCode php\"><span id=\"cb7-1\"><a href=\"#cb7-1\" aria-hidden=\"true\" tabindex=\"-1\"></a><span class=\"fu\">define</span>( <span class=\"st\">&#39;CREATIONELL_CAPTCHA_DISABLE&#39;</span><span class=\"ot\">,</span> <span class=\"kw\">true</span> )<span class=\"ot\">;</span></span></code></pre></div>\n<p>Sofort sind <strong>alle</strong> Module aus — Firewall, Rate-Limit,\nCaptcha, Under-Attack, Interceptor. Anschließend lassen sich die\nproblematischen Einstellungen im Backend korrigieren. Ohne\nSSH/FTP-Zugriff bleibt der direkte Datenbank-Eingriff:\n<code>wp option update creationell_captcha_settings …</code> oder per\n<code>wp creacaptcha settings load-defaults</code>.</p>\n<h3\nid=\"funktioniert-das-plugin-hinter-cloudflare-oder-einem-reverse-proxy\">Funktioniert\ndas Plugin hinter Cloudflare oder einem Reverse-Proxy?</h3>\n<p>Ja. Im Tab <strong>Firewall</strong> unter „Proxy &amp;\nIP-Ermittlung” den Proxy-Modus aktivieren und den passenden\nForwarded-Header wählen. Für Cloudflare zusätzlich „Cloudflare-IPs\nvertrauen” und optional den Auto-Refresh einschalten — die offiziellen\nCloudflare-v4/v6-Ranges werden dann täglich neu geladen. Ohne\nTrust-Konfiguration wird der Header ignoriert, damit Angreifer nicht\nbeliebige IPs spoofen können.</p>\n<h3 id=\"wie-viel-performance-kostet-das-plugin\">Wie viel Performance\nkostet das Plugin?</h3>\n<p>Sehr wenig. Die Captcha-Berechnung läuft im Browser, nicht auf dem\nServer. Die Firewall-Auswertung ist eine reine IP-/Pattern-Prüfung\n(keine externen Lookups). Analytics-Counter werden seit v0.26.0 pro\nRequest gesammelt und in einem einzigen DB-Roundtrip auf\n<code>shutdown</code> geschrieben. Das Event-Log nutzt seit derselben\nVersion einen Composite-Index, der typgefilterte Dashboard-Queries ohne\nFilesort beantwortet.</p>\n<h3 id=\"wie-dsgvo-konform-ist-das-plugin\">Wie DSGVO-konform ist das\nPlugin?</h3>\n<p>Out-of-the-box ist die IP-Anonymisierung im Event-Log aktiv (IPv4 auf\nletztes Oktett, IPv6 auf letzte 80 Bit trunkiert). Aggregat-Zähler\nenthalten keinerlei personenbezogene Daten. Im Event-Log werden keine\nQuery-String-Werte (GET-Token, Magic-Links, API-Keys) gespeichert — der\nPfad wird vor dem Schreiben auf den reinen Pfadanteil reduziert.\nRequest-Body-Fingerprints enthalten nur Feldnamen und Wertlängen;\nsensitive Feldnamen werden zusätzlich gehasht.</p>\n<h3 id=\"wie-deaktiviere-ich-das-plugin-sauber\">Wie deaktiviere ich das\nPlugin sauber?</h3>\n<p>Über <strong>Plugins → Installierte Plugins</strong> deaktivieren\nreicht für den Betrieb. Wer auch die Daten loswerden will, kann das\nPlugin anschließend löschen — der <code>uninstall.php</code>-Cleanup\nentfernt alle Options, Transients (inklusive <code>_cc_*</code>-Caches\nund <code>_git_update_*</code>-Locks) sowie die Event-Tabelle.</p>\n<h3 id=\"funktioniert-das-plugin-mit-multisite\">Funktioniert das Plugin\nmit Multisite?</h3>\n<p>Ja, allerdings pro Site einzeln aktivierbar. Es gibt aktuell keine\nNetwork-Activate-Logik mit zentralen Settings — jede Site hat ihre\neigene Konfiguration. Network-weite Aktivierung ist möglich, hat aber\ndenselben Effekt wie eine Aktivierung pro Site.</p>\n<h3\nid=\"kann-ich-creacaptcha-parallel-zu-einem-anderen-captcha-plugin-betreiben\">Kann\nich CreaCaptcha parallel zu einem anderen Captcha-Plugin betreiben?</h3>\n<p>Technisch ja — die Code-Pfade kollidieren nicht.\n<code>wp creacaptcha doctor</code> prüft auf bekannte Captcha-Plugins\n(reCAPTCHA, hCaptcha, Turnstile, ALTCHA-WordPress) und warnt, weil zwei\nCaptcha-Layer auf demselben Formular für den Nutzer unzumutbar werden.\nEmpfehlung: nur eines aktiv lassen.</p>\n<h3 id=\"wo-finde-ich-logs-wenn-etwas-nicht-funktioniert\">Wo finde ich\nLogs, wenn etwas nicht funktioniert?</h3>\n<p>Mit <code>define( 'CREATIONELL_CAPTCHA_DEBUG', true );</code> (oder\nglobal <code>WP_DEBUG</code>) schreibt das Plugin Debug-Hinweise nach\n<code>wp-content/debug.log</code>. Zusätzlich liefert\n<code>wp creacaptcha doctor</code> einen kompletten Diagnose-Lauf, und\ndas Event-Log zeigt alle abgewiesenen Requests samt Grund.</p>\n<h3 id=\"wie-aktualisiere-ich-auf-eine-neue-version\">Wie aktualisiere ich\nauf eine neue Version?</h3>\n<p>Drei Wege: (1) Der eingebaute Self-Hosted-Updater zeigt neue\nVersionen automatisch im <strong>Plugins</strong>-Bildschirm — wie ein\nnormales wp.org-Update. (2) ZIP von der GitHub-Release-Seite\nherunterladen und manuell über <strong>Plugins → Installieren → Plugin\nhochladen</strong> einspielen. (3) Per WP-CLI:\n<code>wp plugin install --activate &lt;release-url&gt;</code> mit der\nURL aus den GitHub-Releases.</p>\n<hr />\n<h2 id=\"changelog\">Changelog</h2>\n<h3 id=\"section\">1.0.1</h3>\n<ul>\n<li>Fix: Contributor-Einträge im Plugin-Detail-Popup erhalten jetzt\neinen <code>display_name</code> — zuvor loggte WordPress-Core eine\nPHP-Warning und zeigte die Contributor-Namen nicht an. Das\nUpdate-Manifest liefert das Feld nun mit; der Updater ergänzt es als\nFallback auch für ältere Manifeste.</li>\n<li>Fix: Der <code>no_update</code>-Eintrag des Updaters enthält jetzt\n<code>new_version</code>, <code>package</code>, <code>tested</code> und\n<code>requires_php</code> — zuvor loggte WP-CLI bei\n<code>wp plugin list</code> eine PHP-Warning, wenn das Plugin aktuell\nwar.</li>\n<li>Entfernt: Der seit v0.19.0 veraltete WP-CLI-Alias\n<code>wp creacaptcha refresh-cloudflare-ips</code>. Bitte\n<code>wp creacaptcha cloudflare refresh</code> verwenden.</li>\n<li>Verbessert: Die Plugin-Banner werden jetzt verlustfrei als AVIF\nkodiert.</li>\n</ul>\n<h3 id=\"section-1\">1.0.0</h3>\n<p>Erstes stabiles Release. CreaCaptcha ist ein vollständig\nselbst-gehosteter Spamschutz für WordPress — ohne externe Dienste, ohne\nTracking, ohne Lizenz-Gate.</p>\n<p>Funktionsumfang:</p>\n<ul>\n<li>Proof-of-Work-Captcha (ALTCHA-kompatibel, PBKDF2/Argon2id) für\nKommentare, Login, Registrierung und Passwort-Reset</li>\n<li>Formular-Integrationen: Contact Form 7, Forminator, WPForms,\nWooCommerce (Checkout, Login, Registrierung, Lost-Password)</li>\n<li>Generischer Interceptor für beliebige URL-Pfade und\nWordPress-Actions</li>\n<li>Firewall (IP-/CIDR-/User-Agent-Listen), per-IP-Rate-Limiter,\nProxy-Support inkl. Cloudflare</li>\n<li>Under-Attack-Modus mit anpassbarer 503-Interstitial-Seite (Texte,\nFarben, Logo, Custom-CSS)</li>\n<li>Bild-Code-Challenge als optionale zweite Captcha-Stufe</li>\n<li>E-Mail-Obfuskation (Content-Filter oder Ganzseiten-Buffer)</li>\n<li>Statistik-Dashboard, Event-Log mit Suche/Filter/CSV-Export</li>\n<li>Umfassende WP-CLI-Integration (<code>wp creacaptcha …</code>)</li>\n<li>Widget-Anpassung (Themes, Farben, Custom-CSS, 20 Sprachen)</li>\n</ul>\n<p>Neu in diesem Release:</p>\n<ul>\n<li>Plugin-Banner für den WordPress-Update-Screen</li>\n<li>Dokumentations-Sektion in der README (Web-Doku, Update-Manifest,\nAPI-Referenz)</li>\n<li>Contributors-Angabe im Update-Manifest erweitert</li>\n</ul>\n<p>Das Update von v0.30.x erfolgt ohne Datenbank-Migration und ohne\nBreaking Changes — bestehende Einstellungen, Listen und Statistiken\nbleiben unverändert erhalten.</p>\n<h3 id=\"section-2\">0.30.1</h3>\n<p>Wartungsrelease: Release-Infrastruktur umgestellt — keine\nfunktionalen Änderungen am Plugin.</p>\n<ul>\n<li>Die Plugin-Releases werden ab dieser Version aus dem dedizierten,\nöffentlichen Release-Repository\n<code>github.com/creationell-dev/creationell-captcha</code>\nveröffentlicht. Download-, Update- und Dokumentations-URLs bleiben\nunverändert.</li>\n<li>Build-Pipeline gehärtet: GitHub-Actions und phpDocumentor auf feste\nVersionen gepinnt, Build-Staging vom Paketinhalt ausgeschlossen.</li>\n</ul>\n<h3 id=\"section-3\">0.30.0</h3>\n<p>Under-Attack Pass-Event &amp; Statistik-Übersicht — das Backend\nunterscheidet jetzt, ob ein Besucher die Under-Attack-Prüfung bestanden\nhat oder hängen blieb, und die Statistik-Übersicht erklärt ihre Zahlen\nselbst.</p>\n<ul>\n<li>Neuer Event-Typ <code>underattack_passed</code>: feuert, wenn ein\nBesucher die Under-Attack-PoW-Prüfung löst und das Pass-Cookie\nausgestellt wird. Erscheint in Übersicht, Verlauf, Ereignis-Filter,\nCSV-Export und WP-CLI (<code>wp creacaptcha stats</code>,\n<code>log list --type=underattack_passed</code>).</li>\n<li>Neues Log-Gate „Bestandene Under-Attack-Prüfungen loggen” (Default:\nan); Aggregat-Zähler laufen unabhängig davon.</li>\n<li>Statistik-Übersicht: vier KPI-Kacheln statt drei — „Abgewehrt (24\nh)” zählt nur noch echte Blocks (Firewall + Rate-Limit), Under-Attack\nhat eine eigene Kachel „Abfragen / bestanden”.</li>\n<li>Statistik-Übersicht: die flache Ereignis-Tabelle ist in vier\nthematische Gruppen mit Erklärungstext gegliedert (Formular-Captchas /\nAbgewehrte Zugriffe / Under-Attack-Modus / Technisch); nicht zugeordnete\nTypen landen automatisch in einer Auffanggruppe „Weitere\nEreignisse”.</li>\n<li>Keine DB-Migration nötig; bestehende Events und Zähler bleiben\nunverändert gültig.</li>\n</ul>\n<h3 id=\"section-4\">0.29.0</h3>\n<p>Logo im Under-Attack-Interstitial — die 503-Seite kann jetzt ein Logo\noberhalb der Überschrift anzeigen.</p>\n<ul>\n<li>Neues optionales Feld „Logo-URL” in der Under-Attack-Section\n„Erscheinungsbild”. Leer = kein Logo (Default); bestehende Sites sehen\nohne Aktion keine Änderung.</li>\n<li><code>UnderAttack::serve_interstitial()</code> reicht die URL als\n<code>$logo_url</code> ans Template; das Template rendert ein\nzentriertes <code>&lt;img class=\"crea-ua-logo\"&gt;</code> vor dem\n<code>&lt;h1&gt;</code>, gedeckelt auf <code>max-height: 128px</code>.\nAlt-Text = Website-Name (<code>get_bloginfo('name')</code>).</li>\n<li>Sanitization via <code>esc_url_raw()</code> beim Speichern\nentschärft gefährliche Schemata (<code>javascript:</code> o. Ä.);\nAusgabe zusätzlich mit <code>esc_url()</code>.</li>\n<li>Größe per <code>.crea-ua-logo</code> über das vorhandene „Eigenes\nCSS”-Feld überschreibbar. Setzbar über\n<code>wp creacaptcha settings set   underattack_logo_url &lt;url&gt;</code>.</li>\n</ul>\n<h3 id=\"section-5\">0.28.0</h3>\n<p>Feature-Modul 21 — Under-Attack-Customization: Wording und\nErscheinungsbild der Interstitial-Seite sind ab sofort über das Backend\nkonfigurierbar, ohne Plugin-Code zu patchen.</p>\n<ul>\n<li>Neue Section „Erscheinungsbild” im Under-Attack-Tab mit sieben\noptionalen Feldern: vier Texte (Browser-Tab-Titel, Überschrift,\nHinweistext, NoScript-Hinweis), zwei Farben (Hintergrund, Textfarbe) und\nein freies Custom-CSS-Feld.</li>\n<li>Renderer in <code>UnderAttack::serve_interstitial()</code> baut die\ndrei Variablen <code>$texts</code> / <code>$colors</code> /\n<code>$user_css</code> und reicht sie ans Template weiter; leere Felder\nfallen auf die existierenden Hartcode-Defaults zurück.</li>\n<li>Template (<code>includes/under-attack-interstitial.php</code>) nutzt\nzwei neue CSS-Variablen <code>--creationell-captcha-ua-bg</code> und\n<code>--creationell-captcha-ua-text</code> für die Farben. Ein zweiter\n<code>&lt;style&gt;</code>-Block direkt nach dem Default-Stylesheet\nnimmt das Custom-CSS auf — alle Regeln des Defaults sind dort\nüberschreibbar.</li>\n<li>Sanitization analog zu <code>widget_custom_css</code>:\n<code>wp_strip_all_tags()</code> neutralisiert\n<code>&lt;/style&gt;&lt;script&gt;</code>-Injection bevor der Wert die\nTemplate-Ausgabe erreicht.</li>\n<li>Alle sieben Felder sind über das bestehende\n<code>wp creacaptcha settings set &lt;key&gt; &lt;value&gt;</code>-CLI\nsetzbar — neue Field-Typen waren nicht nötig, alle Typen\n(<code>text</code>, <code>color</code>, <code>textblock</code>) gibt es\nseit Modul 14.</li>\n</ul>\n<p>Sites nach Update sehen ohne Aktion <strong>keine</strong> visuelle\nVeränderung — alle sieben Felder sind initial leer und das Template\nfällt damit auf die bisherigen Default-Werte zurück.</p>\n<h3 id=\"section-6\">0.27.2</h3>\n<p>Metadaten-Anpassung an WordPress 7.0 / 6.9.</p>\n<ul>\n<li><strong>Plugin-Header &amp; README:</strong>\n<code>Requires at least</code> von 6.8 auf 6.9 angehoben,\n<code>Tested up to</code> von 6.8 auf 7.0 nachgezogen. WordPress 7.0 ist\nseit kurzem produktiv; der Plugin-Test-Lauf der bisherigen Module 1–20\nist gegen 7.0 sauber.</li>\n<li><strong>Konstante:</strong> <code>CREATIONELL_CAPTCHA_MIN_WP</code>\nvon <code>'6.8'</code> auf <code>'6.9'</code> angehoben. Sites auf\nWordPress 6.8 oder älter erhalten beim Aktivieren jetzt die bestehende\nHinweisleiste „Erfordert WordPress 6.9 oder neuer.” statt das Plugin zu\nladen.</li>\n<li>Inline-Kommentar im Plugin-Bootstrap (<code>WordPress 6.8+</code> →\n<code>WordPress 6.9+</code>) und die interne Entwickler-Dokumentation\nkonsistent nachgezogen.</li>\n</ul>\n<p>Keine funktionalen Code-Änderungen.</p>\n<h3 id=\"section-7\">0.27.1</h3>\n<p>CSS-Fix: Widget-Abstand zum darauffolgenden Element im\nStandard-Modus.</p>\n<ul>\n<li><code>assets/css/widget.css</code>: Die Block-Flow-Abstandsregel auf\n<code>&lt;altcha-widget&gt;</code> ist von <code>margin-block-end</code>\nauf <code>padding-block-end</code> umgestellt und auf den\n<code>display=\"standard\"</code>-Modus eingeschränkt. Hintergrund: das\nWidget ist auf den geschützten Formularen typischerweise das letzte Kind\nim <code>&lt;form&gt;</code> — der bisherige\n<code>margin-block-end</code> kollabierte deshalb mit der Bottom-Kante\ndes Form-Elements (kein\n<code>padding-bottom</code>/<code>border-bottom</code>/eigene BFC),\nsodass visuell überhaupt kein Abstand zum nachfolgenden Inhalt blieb.\nPadding kollabiert nicht — der konfigurierbare Abstand (Default jetzt\n<code>1rem</code> statt <code>1.5em</code>) ist daher zuverlässig\nsichtbar. Der CSS-Variablenname\n(<code>--creationell-captcha-widget-margin-block-end</code>) bleibt aus\nKompatibilitätsgründen gleich.</li>\n<li>Floating/Overlay/Bar/Invisible-Modi bekommen den Abstand nicht mehr\nspurious mitgegeben — ihre eigentliche Widget-Darstellung ist\nposition-fixed bzw. display:none, ein Inline-Spacer wäre dort nur ein\ntoter 1.5em-Gap.</li>\n</ul>\n<h3 id=\"section-8\">0.27.0</h3>\n<p>Feature-Modul 20 — Widget-i18n: Die Sicherheitsabfrage erscheint\nendlich in der korrekten Sprache, ohne dass der Admin etwas\nkonfigurieren muss.</p>\n<ul>\n<li>Neue 20 vendorierte ALTCHA-Locale-Dateien unter\n<code>assets/js/altcha-i18n/</code> (DE, EN, FR-FR/CA, ES-ES/419, IT,\nNL, PT-PT/BR, PL, CS, SK, DA, SV, FI, NB, HU, RO, EL) — je ~3 KB,\nPage-Load lädt weiterhin nur eine Datei.</li>\n<li>Neuer Helper\n<code>creationell_captcha_resolve_widget_locale()</code> mit\nLookup-Tabelle (48 WP-Locale-Strings, inkl. formal/informal- Varianten)\nauf 20 ALTCHA-Codes.</li>\n<li><code>creationell_captcha_build_widget_markup()</code> enqueued die\npassende Locale-Datei lazy (analog zum Theme-CSS-Pattern) und setzt\n<code>language=\"&lt;code&gt;\"</code> am\n<code>&lt;altcha-widget&gt;</code>. Locales ohne Mapping überspringen\nbeide Schritte — das Widget nutzt dann seine eigene\n<code>&lt;html lang&gt;</code>/Browser-Detection.</li>\n<li>Zwei neue Filter <code>creationell_captcha_widget_locale_map</code>\nund <code>creationell_captcha_widget_locale</code> für Projekt-Overrides\nohne Plugin-Patch.</li>\n<li><code>wp creacaptcha status</code> zeigt eine neue Zeile\n„Widget-Sprache” mit dem effektiven ALTCHA-Code plus dem\nWP-Locale-Ursprung.</li>\n<li><code>widget_strings_override</code> bleibt unverändert und greift\nweiterhin als Pro-Schlüssel-Override <strong>on top</strong> der\nAuto-Locale.</li>\n</ul>\n<h3 id=\"section-9\">0.26.2</h3>\n<p>Bugfix-Release: schließt eine Verify-Regression aus v0.22.0 / Commit\n<code>c322b96</code>, die seit der Korrektur des\n<code>configuration</code>-JSON-Attributs das ALTCHA-Widget dazu\nbrachte, bei jedem gelösten PoW die <code>/code-verify</code>-Route\naufzurufen — und dort mit 400 <code>invalid_request</code> abgewiesen zu\nwerden, weil im Plain-Mode (ohne Code-Challenge im\n<code>/challenge</code>-Response) das <code>code</code>-Feld im Body\nfehlt.</p>\n<ul>\n<li><code>includes/widget.php</code>: <code>verifyUrl</code> wird im\n<code>configuration</code>-JSON nur noch dann emittiert, wenn das\nMaster-Setting <code>code_challenge_enabled</code> aktiv ist. Im\nStandardfall (Code-Challenge aus) verifiziert das Widget wieder rein\nclient-seitig, ohne den überflüssigen Server-Roundtrip.</li>\n<li><code>includes/code-challenge.php</code>: <code>/code-verify</code>\nakzeptiert das <code>code</code>-Feld jetzt als optional. Plain-Mode\n(<code>{ payload }</code> ohne <code>code</code>) durchläuft\n<code>Engine::verify_structural()</code>, prüft die Original-Signatur\nüber den gleichen Single-Use-Transient-Schlüssel wie\n<code>Engine::verify()</code> (verhindert, dass eine einzelne gelöste\nPoW in N frische Payloads multipliziert wird) und gibt eine frische\nsignierte Payload zurück. Code-Challenge-Modus bleibt funktional\nunverändert.</li>\n</ul>\n<p>Die ALTCHA-<code>verifyUrl</code>-Mechanik schaltet das Widget\npauschal in den Server-Verify-Modus — auch ohne Code-Challenge im\nResponse. Beide Fixes zusammen: saubere Standard-Konfiguration ohne\nRoundtrip <em>und</em> Defense-in-Depth, falls\n<code>code_challenge_enabled</code> aktiv ist aber kein Trigger\ngreift.</p>\n<h3 id=\"section-10\">0.26.1</h3>\n<p>UX-Polish-Release: schließt die drei nicht-essenziellen UX-Befunde\naus dem Qualitäts-Audit (Modul 18) ab.</p>\n<ul>\n<li>Neue <code>requires_select</code>-Semantik im Settings-Schema:\nFelder können jetzt nicht nur an einen booleschen Vorbedingungs-Toggle\ngekoppelt werden (<code>requires =&gt; 'foo_enabled'</code>), sondern\nauch an einen konkreten Wert eines anderen Select-Feldes\n(<code>requires_select =&gt; ['widget_display' =&gt;   'floating']</code>).\nRender-Layer setzt <code>disabled</code>, Sanitizer-Cascade bewahrt den\ngespeicherten Wert. Anwendung: die drei Floating-Felder\n<code>widget_floating_anchor</code>/<code>widget_floating_placement</code>/\n<code>widget_floating_offset</code> werden jetzt nur aktiv geschaltet,\nwenn der Widget-Anzeige-Modus auf „Schwebend” steht — in jedem anderen\nModus bleiben sie ausgegraut.</li>\n<li>Tools-Page „Auf Werkseinstellungen zurücksetzen”: deutliche\n<code>notice-warning</code>-Box oberhalb der Karte mit Hinweis auf die\nListen-Leerung und Verweis auf die ungefährliche „Standardwerte\nladen”-Karte.</li>\n<li>Wortwahl „Sicherheitsabfrage” (user-facing Help-Texte) vs. „Captcha”\n(technische/Admin-Kontexte wie Tab-Label, Section-Titel, Engine-\nBegriffe) bleibt bestehen — das Audit hat die aktuelle Trennung als\nakzeptabel eingestuft.</li>\n</ul>\n<h3 id=\"section-11\">0.26.0</h3>\n<p>Performance-Release: drei aufgeschobene Optimierungen aus dem\nQualitäts-Audit (Modul 18) — Settings-Memoize, Analytics-Bump-Memoize\nund ein Composite-Index auf der Events-Tabelle.</p>\n<ul>\n<li><code>creationell_captcha_get_settings()</code> cacht das Ergebnis\npro Request in einer statischen Variable. Bisher rief jede\nModul-Komponente (Interceptor, Firewall, Rate-Limiter, Under-Attack,\njede Form- Integration) die Funktion mehrfach pro Request, jedes Mal mit\n<code>array_merge</code> über ~70 Default-Keys. Invalidierung läuft über\ndie\n<code>update_option</code>/<code>add_option</code>/<code>delete_option</code>-Hooks\nfür <code>creationell_captcha_settings</code>, sodass Caller direkt nach\neinem Speichervorgang den frischen Wert sehen.</li>\n<li><code>Analytics::record()</code> sammelt die Daily- und\nHourly-Counter-Deltas in request-lokalen Static-Caches und flusht sie\nvia <code>add_action('shutdown', …)</code> in genau einem\n<code>get_option</code>/<code>update_option</code>-Paar pro\nCounter-Tabelle. Vorher: zwei Roundtrips pro Event — eine\n<code>/challenge</code>-Route mit aktivem\n<code>log_challenge</code>-Toggle und nachgelagerter Verifikation kommt\ndamit bei 4–6 Roundtrips an. Jetzt: maximal 2 Roundtrips, unabhängig von\nder Anzahl der Events. Die Cutoff-Pruning-Logik wandert in\n<code>apply_deltas()</code> und läuft jetzt einmal je Counter statt\neinmal je Event. Konkurrente Updates aus parallelen Requests bleiben\nerhalten (Flush liest frischen Stand und addiert nur die eigenen\nDeltas).</li>\n<li>Composite-Index\n<code>event_type_created (event_type, created_at)</code> auf der\nEvents-Tabelle. Dashboard-Queries mit <code>event_type</code>-Filter\n(Statistik-Tab, CSV-Export, Detail-Modal-Source) erzwangen bisher einen\nFilesort über den per-day-gesliceten Range. Mit dem Composite-Index\nläuft die typgefilterte Range-Abfrage als reiner Index-Range-Scan.\nMigration via <code>Analytics::ensure_table()</code> — dbDelta für\nFrischinstalls, <code>SHOW INDEX</code>-Guard plus\n<code>ALTER TABLE</code> als Fallback für bestehende Tabellen (dbDelta\nist für Index-Adds historisch unzuverlässig).\n<code>%i</code>-Identifier-Platzhalter konsistent mit\n<code>clear_events()</code>.</li>\n</ul>\n<h3 id=\"section-12\">0.25.0</h3>\n<p>Qualitäts-Audit-Release: Security-Härtung des Updaters,\nEvent-Log-Privacy, Body-Fingerprint-Maskierung sowie umfassende\nUX-Hilfetexte und Konsistenz- Fixes im Backend.</p>\n<p><strong>Sicherheit:</strong> - Updater\n(<code>includes/class-plugin-updater.php</code>): Checksum-Vergleich\nnutzt jetzt <code>hash_equals()</code> (timing-safe). Slug-Heuristik in\n<code>verify_download_checksum()</code> durch Exakt-Match gegen\n<code>manifest.download_url</code> ergänzt — verhindert Bypass über ein\nmanipuliertes Manifest mit Slug-freier Download-URL. Manifest-Fetch über\n<code>wp_safe_remote_get()</code> (Defense-in-Depth gegen SSRF). -\nEvent-Log: <code>Analytics::current_path()</code> reduziert\n<code>REQUEST_URI</code> auf den Pfad-Anteil. GET-Token,\nMagic-Login-Links und API-Keys landen damit nicht mehr im persistenten\nEvent-Log. - Request-Body-Fingerprint: Feldnamen mit sensitiven\nSubstrings (<code>password</code>, <code>secret</code>,\n<code>token</code>, <code>iban</code>, <code>api_key</code>,\n<code>cvv</code>, …) werden vor dem JSON-Encode durch\n<code>[masked:&lt;sha256-8&gt;]</code> ersetzt, um Custom-Form- Schemata\nnicht im Event-Log preiszugeben. Neuer Filter\n<code>creationell_captcha_request_body_sensitive_patterns</code> für\nprojektspezifische Erweiterungen. -\n<code>Analytics::clear_events()</code> nutzt jetzt\n<code>wpdb::prepare( 'DELETE FROM %i',   $table )</code> statt\nRoh-Interpolation (WP-6.2+-konform).</p>\n<p><strong>Backend-UX:</strong> - DSGVO-First: Default\n<code>analytics_anonymize_ip</code> von <code>false</code> auf\n<code>true</code>. Neue Installs anonymisieren IPs out-of-the-box;\nbestehende Installs behalten ihre Wahl. - Rate-Limit-Default\n<code>ratelimit_max</code> von 10 auf 30 (besser für Login-Scope — ein\nNutzer mit Tippfehler-Marathon läuft nicht mehr ins 5-Minuten-Lockout).\n- Tab-Reihenfolge: „Analytics” steht nun vor „E-Mail-Schutz” (näher an\nden Schutzmodulen). - Firewall-Tab: Sektionen sortiert auf Proxy →\nFirewall → Bypass → Rate-Limit (Bypass folgt der Firewall, deren Regeln\nsie überstimmt). - <code>widget_code_challenge_display</code> in die\nCode-Challenge-Section verschoben und an\n<code>code_challenge_enabled</code> gekoppelt. - 21 fehlende oder\nschwache Settings-Hilfetexte ergänzt (<code>algorithm</code>,\n<code>difficulty</code>, <code>challenge_expiry</code>, alle\n<code>widget_*</code>-Customization-Felder, Core-Forms-Toggles, alle\nForm-Plugin-Toggles, Rate-Limit-Felder,\n<code>firewall_proxy_header</code>,\n<code>firewall_ip_block</code>/<code>ua_block</code>,\n<code>underattack_enabled</code>, <code>analytics_event_log</code>,\n<code>bypass_cookies</code>,\n<code>firewall_cloudflare_auto_refresh</code>,\n<code>interceptor_skip_logged_in</code>). Section-Renderer für Engine,\nCode-Challenge und Firewall mit erklärenden Texten ergänzt (PoW-Konzept,\nOR-Logik der Trigger, CIDR-Notation). -\n<code>interceptor_actions</code>-Hilfetext nennt jetzt die\n<code>edit_posts</code>-Exemption (Autoren/Editoren weiterhin\nausgenommen). - Tools-Page: Reset-Karte + Confirm-Dialog erwähnen jetzt\nexplizit auch Interceptor- und Bypass-Listen.</p>\n<p><strong>WP-CLI:</strong> - <code>wp creacaptcha status</code> zeigt\ndrei neue Zeilen: Proxy-Modus, CF-Trust / CF-Auto-Refresh und\nIP-Anonymisierung. - <code>wp creacaptcha doctor</code> prüft\n<code>ext-sodium</code>, wenn der Algorithmus auf Argon2id steht — Error\nmit Fix-Vorschlag, wenn die Extension fehlt.</p>\n<p><strong>Code-Qualität:</strong> -\n<code>defined( constant_name: 'ABSPATH' )</code> →\n<code>defined( 'ABSPATH' )</code> in 48 Dateien. Named-Args auf\nPHP-Builtins sind nicht stabilitäts-garantiert und werden von\nStatic-Analyzern als Anti-Pattern geflaggt. - PHPDoc: über 20 eigene\n<code>do_action</code>/<code>apply_filters</code>-Hooks vollständig\ndokumentiert (<code>creationell_captcha_event</code>,\nInterceptor-Filter-Familie, WPForms-/WC-Autoinject-Filter),\nRepeat-Dispatches mit WordPress-Core- style „This action is documented\nin …“-Verweisen. - REST-Callback-PHPDocs in\n<code>includes/rest.php</code> und\n<code>includes/code-challenge.php</code> ergänzt\n(<code>@param</code>/<code>@return</code> mit Status-Code-Tabelle).</p>\n<p><strong>Tooling &amp; Doku:</strong> - <code>phpdoc.xml</code>\nVersion-Drift <code>0.1.0</code> → <code>0.25.0</code>. -\nPlugin-Header-Description nennt jetzt Firewall, Rate-Limit,\nUnder-Attack, E-Mail-Obfuskation und Code-Challenge (vorher: nur\nPoW-Spamschutz). - README-Description um WPForms-,\nWooCommerce-Integrationen und Code-Challenge-Absatz erweitert. -\n<code>uninstall.php</code>: Transient-Cleanup vom\n<code>_used_</code>-Prefix auf das gesamte\n<code>creationell_captcha_</code>-Prefix erweitert; entfernt jetzt auch\n<code>_cc_*</code>, <code>_rl_*</code> und\n<code>_git_update_*</code>-Caches/Locks.</p>\n<p><strong>Behebt:</strong> - Inkorrekt formulierter\nIPv6-Anonymisierungs-Hilfetext (<code>includes/settings.php</code>):\nstimmt jetzt mit der Code-Logik überein (erste 48 Bit bleiben, letzte 80\nBit auf 0). - Tippfehler „mehrmietigen” → „mehrmandantigen (Shared\nHosting)“. - <code>Tested up to: 6.9</code> → <code>6.8</code>\n(WordPress 6.9 ist Stand 2026-05-28 noch nicht released).</p>\n<h3 id=\"section-13\">0.24.0</h3>\n<ul>\n<li>WP-CLI-Nachzug Phase 2: schließt sieben CLI-Coverage-Lücken nach den\nModulen 14–16.</li>\n<li>Neuer Listen-Befehl\n<code>wp creacaptcha watchlist add|remove|list|clear</code> für die\nCode-Challenge-Watchlist (<code>code_challenge_watchlist</code>).</li>\n<li><code>wp creacaptcha status</code> zeigt sechs zusätzliche Zeilen:\nForm-Plugin- Toggles (CF7, Forminator, WPForms, WooCommerce + gruppierte\nZeile für die vier Woo-Sub-Toggles) und den\nWatchlist-Eintragszähler.</li>\n<li><code>wp creacaptcha enable code-challenge</code> /\n<code>disable code-challenge</code> togglet\n<code>code_challenge_enabled</code> über <code>feature_map()</code>.\nDoc-Strings von <code>enable</code>/<code>disable</code> listen jetzt\nalle 19 Features (vorher 12, fehlten WPForms, WooCommerce und die vier\nwc-* Mappings).</li>\n<li><code>wp creacaptcha settings set</code> unterstützt jetzt\nzusätzlich die Feldtypen <code>text</code>, <code>color</code> und\n<code>textblock</code> — damit werden die Widget-Customization-Felder\n(<code>widget_floating_anchor</code>, <code>widget_primary_color</code>,\n<code>widget_custom_css</code>, <code>widget_strings_override</code>)\nüber die CLI setzbar. Verworfene JSON-/Hex-Werte werden via\n<code>WP_CLI::warning()</code> gemeldet.</li>\n<li><code>wp creacaptcha doctor</code> ergänzt einen GD-Extension-Check:\nwenn <code>code_challenge_enabled</code> aktiv ist, muss die\nPHP-GD-Extension geladen sein (sonst <code>error</code> mit Exit-Code\n1).</li>\n<li><code>wp creacaptcha log list</code> unterstützt jetzt\n<code>--fields=</code> (WP-CLI- Standard); Default-Output bleibt die\nbisherige 4-Spalten-Übersicht, verfügbar werden alle 15 Spalten der\nEvent-Log-Tabelle.</li>\n<li>Neuer Befehl <code>wp creacaptcha log show &lt;id&gt;</code> zeigt\neinen einzelnen Event mit allen 15 Spalten als Key-Value-Tabelle (oder\nJSON/YAML/CSV via <code>--format</code>).</li>\n</ul>\n<h3 id=\"section-14\">0.23.0</h3>\n<ul>\n<li>WPForms-Integration: Neues Setting „WPForms schützen” im\nFormulare-Tab. Aktiv, sobald das WPForms-Plugin installiert ist.\nAuto-Inject des Widgets vor dem Submit-Button\n(<code>wpforms_display_submit_before</code>); Verify über\n<code>wpforms_process</code>-Action, Fehlerausgabe via\n<code>wpforms()-&gt;process-&gt;errors[$form_id]['header']</code>.</li>\n<li>WooCommerce-Integration: Master-Toggle „WooCommerce schützen” plus\nvier Sub-Toggles für Checkout, My-Account-Login,\nMy-Account-Registrierung und Lost-Password. Auto-Inject auf den nativen\nWoo-Hooks (<code>woocommerce_review_order_before_submit</code>,\n<code>woocommerce_login_form_end</code>,\n<code>woocommerce_register_form</code>,\n<code>woocommerce_lostpassword_form</code>); Verify auf\n<code>woocommerce_after_checkout_validation</code>,\n<code>woocommerce_process_login_errors</code>,\n<code>woocommerce_registration_errors</code>.</li>\n<li>Lost-Password ist Render-only: Server-Verifikation läuft über\n<code>protect_password_reset</code> (WordPress-Kernformular), weil\nWoo-Lost-Password über WP-Core <code>retrieve_password()</code>\nzurückläuft und damit <code>lostpassword_post</code> feuert.</li>\n<li>Produkt-Bewertungen werden bewusst nicht über einen eigenen\nSub-Toggle abgebildet — Reviews sind WordPress-Kommentare und durch\n<code>protect_comments</code> abgedeckt; der Hilfetext am Master-Toggle\nweist darauf hin.</li>\n<li>Render-Override-Filter (alle fünf, einheitliche\n<code>(bool, int $form_id)</code>- Signatur):\n<code>creationell_captcha_wpforms_autoinject</code>,\n<code>creationell_captcha_wc_checkout_autoinject</code>,\n<code>creationell_captcha_wc_login_autoinject</code>,\n<code>creationell_captcha_wc_registration_autoinject</code>,\n<code>creationell_captcha_wc_lost_password_autoinject</code>. Bei\n<code>false</code> wird das Auto-Inject übersprungen; die Verifikation\nbleibt aktiv.</li>\n<li>WP-CLI: sechs neue Feature-Schlüssel für\n<code>wp creacaptcha enable|disable</code> — <code>wpforms</code>,\n<code>woocommerce</code>, <code>wc-checkout</code>,\n<code>wc-login</code>, <code>wc-registration</code> und\n<code>wc-lost-password</code>.</li>\n<li>Bypass-Kette und Kill-Switch wirken wie bei den bestehenden\nIntegrationen: jeder Verify-Pfad ruft\n<code>creationell_captcha_request_bypassed()</code> und respektiert\n<code>CREATIONELL_CAPTCHA_DISABLE</code>.</li>\n</ul>\n<h3 id=\"section-15\">0.22.0</h3>\n<ul>\n<li>Widget-Bugfix: Der\nALTCHA-<code>&lt;altcha-widget&gt;</code>-Custom-Element-Tag erkennt nur\n9 spezifische HTML-Attribute (<code>auto</code>, <code>challenge</code>,\n<code>configuration</code>, <code>display</code>, <code>language</code>,\n<code>name</code>, <code>theme</code>, <code>type</code>,\n<code>workers</code>) — alle anderen Props (Verify-URL,\nFloating-Anchor/Placement/Offset, Code-Challenge- Display,\nHide-Footer/Logo, Strings-Override) müssen als JSON-Blob über das\n<code>configuration</code>-Attribut übergeben werden. Bisher hat das\nPlugin diese Settings als Einzelattribute emittiert, die das Widget\nstillschweigend ignoriert hat. Sichtbare Folgen: Floating-Anchor griff\nnicht, ALTCHA-Footer/Logo blieben sichtbar, Code-Challenge-Modal-Modi\n(overlay/bottomsheet) wurden ignoriert, eigene Übersetzungen waren\nwirkungslos. Mit v0.22.0 wirken alle Modul-14-Settings korrekt — das ist\neine Verhaltensänderung, falls jemand diese Felder auf Nicht- Default\ngesetzt hatte.</li>\n<li>Bild-Code-Challenge: Zweite Captcha-Stufe nach der\nProof-of-Work-Verifikation — ein vom Server ausgestelltes PNG mit einem\n4–8-stelligen Code, den der User abtippen muss. Self-hosted, kein\nexterner Dienst, kein ALTCHA Sentinel.</li>\n<li>Neue Section „Bild-Code-Challenge” im Captcha-Tab mit Master-Toggle\nund drei unabhängigen Trigger-Bedingungen: Under-Attack-Modus,\nRate-Limit- Schwellwert (konfigurierbar 50–95 %) sowie eine eigene\nWatch-Liste von IPs/CIDRs. Mehrere Trigger gleichzeitig sind\nOR-verknüpft.</li>\n<li>Code-Optionen: Länge 4–8, Zeichensatz (nur Ziffern / alphanumerisch\n/ alphanumerisch ohne Verwechsler), Token-Gültigkeit 60–900\nSekunden.</li>\n<li>Zwei neue REST-Endpoints:\n<code>GET /wp-json/creationell-captcha/v1/code-image</code> (PNG-Bild)\nund <code>POST /wp-json/creationell-captcha/v1/code-verify</code>\n(Code-Prüfung, liefert eine serverseitig gelöste ALTCHA-Payload, die\ndurch den bestehenden Verifizierungspfad geht). Tokens sind opake\nServer- Identifier (32 Hex), Code lebt nur in einem WP-Transient — kein\nClient-side-Leak des erwarteten Codes.</li>\n<li>Trigger „Immer”: Vierter Trigger-Toggle in der\nCode-Challenge-Section, damit die Code-Challenge unabhängig von\nUnder-Attack / Rate-Limit- Schwelle / Watch-Liste bei jedem\nCaptcha-Request ausgespielt wird — sinnvoll fürs lokale Testen oder\npauschal erhöhte Sicherheit. Default aus.</li>\n<li>Under-Attack-Schutz: Code-Challenge wird auf dem Under-Attack-Inter-\nstitial unterdrückt (das Interstitial-Widget ist invisible — ein Code-\nModal könnte nicht angezeigt werden). Das Interstitial hängt einen\nHMAC-signierten Kontext-Token an die challenge-URL, der nur server-\nseitig signierbar ist; ein Angreifer kann die Suppression nicht selbst\ntriggern.</li>\n<li>Das <code>&lt;altcha-widget&gt;</code> bekommt verifyUrl (sowie alle\nanderen Modul-14- Settings) via das\n<code>configuration</code>-JSON-Attribut, damit es vom Widget überhaupt\ngelesen wird.</li>\n<li>Bild-Rendering via PHP-GD mit vendorierter DejaVuSans-Bold-TTF unter\n<code>assets/fonts/captcha.ttf</code> und naiver Anti-OCR-Verzerrung\n(rotierte Zeichen, Querlinien, Rauschen). Wenn die TTF-Datei fehlt,\nfällt der Renderer auf den GD-Bitmap-Font 5 zurück.</li>\n<li>WP-CLI: <code>wp creacaptcha status</code> zeigt eine neue Zeile\n„Code-Challenge” mit dem effektiven Zustand (<code>an</code> /\n<code>aus</code> / <code>inaktiv (kein GD)</code>).</li>\n<li>Bypass-Schutz: <code>Engine::verify()</code> lehnt jeden Payload ab,\nin dem <code>parameters.data.ccode</code> gesetzt ist — verhindert, dass\nein Angreifer den ursprünglichen Code-Challenge-Payload direkt am\nForm-Submit vorbei einreicht. Frische Payloads aus\n<code>Engine::issue_signed_payload()</code> haben kein\n<code>data.ccode</code> und passieren den Filter.</li>\n<li>Wenn die PHP-GD-Extension fehlt, deaktiviert sich das Feature\nstillschweigend, der bestehende PoW-Flow bleibt unangetastet, und in der\nSettings-Section erscheint eine Warn-Notice.</li>\n</ul>\n<h3 id=\"section-16\">0.21.0</h3>\n<ul>\n<li>Widget: Vendoriert jetzt das ALTCHA-Basis-Stylesheet\n(<code>dist/external/altcha.css</code>) und die sieben Theme-CSS-Files\n(<code>dist/themes/*.min.css</code>). Ohne diese fehlten alle\nDisplay-Modus-Positionierungen (floating/overlay/bar) komplett, und das\nTheme-Attribut hatte keinen sichtbaren Effekt.</li>\n<li>Widget: <code>widget_display</code>-Option <code>bottomsheet</code>\nentfernt — der Wert war kein gültiger ALTCHA-<code>display</code>-Modus\n(nur Inline-Fallback auf standard). Stattdessen neues Setting\n<code>widget_code_challenge_display</code>\n(standard/overlay/bottomsheet) für die ALTCHA-Code-Challenge-Modal, wo\n<code>bottomsheet</code> tatsächlich hingehört.</li>\n<li>Widget: Drei neue Settings für den schwebenden Modus:\n<code>widget_floating_anchor</code> (CSS-Selektor, leer = erster\nSubmit-Button), <code>widget_floating_placement</code>\n(auto/top/bottom), <code>widget_floating_offset</code> (px, 0-200). Ohne\nAnchor bleibt das schwebende Widget off-screen — Help-Text macht das\njetzt klar.</li>\n<li>Update-Procedure für das Widget-Asset auf einen abgesicherten\nnpm-Bezug umgestellt (Schutz vor kompromittierten npm-Paketen).</li>\n<li>Architektur: Neuer Field-Type <code>text</code> (single-line input)\nfür CSS-Selektor- und ähnliche String-Settings.</li>\n</ul>\n<h3 id=\"section-17\">0.20.0</h3>\n<ul>\n<li>Widget: Acht neue Customization-Settings unter „Captcha →\nWidget-Erscheinungsbild”. Display-Modus (standard, floating, overlay,\nbar, invisible, bottomsheet), Interaktions-Typ (checkbox/switch/native),\nautomatische Auslösung (none/onload/onsubmit), eines der acht\nALTCHA-v3-Themes, optionales Ausblenden des ALTCHA-Brandings,\nAkzentfarbe per Color-Picker, eigenes CSS und JSON-Override für die\nWidget-Texte.</li>\n<li>Widget: Das alte zusammengesetzte <code>widget_mode</code>-Setting\n(visible/auto/overlay) entfällt; ein Upgrade-Hook migriert beim ersten\nAdmin-Aufruf automatisch auf die neuen Keys (<code>visible</code> →\nstandard+none, <code>auto</code> → invisible+onload,\n<code>overlay</code> → floating+onsubmit).</li>\n<li>Widget: Der overlay-Modus aus Modul 11a wird jetzt korrekt mit der\nv3- Syntax <code>display=\"floating\"</code> ausgespielt (vorher\nveraltetes <code>floating=\"auto\"</code>).</li>\n<li>Widget: Inline-CSS-Variable\n<code>--creationell-captcha-primary</code> überschreibt die\nALTCHA-Standard-Akzentfarbe, wenn <code>widget_primary_color</code>\ngesetzt ist. Eigenes CSS wird direkt danach ausgegeben und kann beliebig\nüberschreiben.</li>\n<li>WP-CLI: <code>wp creacaptcha status</code> zeigt eine neue Zeile\n„Widget-Anzeige” mit dem aktiven Display-Modus.</li>\n<li>Architektur: Zwei neue Field-Typen <code>color</code> und\n<code>textblock</code> ergänzen das Settings-Framework.\n<code>textblock</code> speichert mehrzeiligen Text ohne die\nLine-Listen-Semantik des bisherigen <code>textarea</code>-Typs.</li>\n</ul>\n<h3 id=\"section-18\">0.19.0</h3>\n<ul>\n<li>WP-CLI: Fünf neue Listen-Subbefehle für die seit v0.13.0\nhinzugekommenen Listen-Settings —\n<code>wp creacaptcha trusted-proxies|bypass-ua|bypass-cookies|actions|inject-paths</code>,\njeweils mit <code>add|remove|list|clear</code>. Damit sind alle Listen\nüber dedizierte Befehle pflegbar, ohne den Umweg über\n<code>settings set</code>.</li>\n<li>WP-CLI: Neue Subcommand-Gruppe\n<code>wp creacaptcha cloudflare</code> mit\n<code>refresh</code>/<code>clear</code>/<code>status</code>. Der alte\nTop-Level-Befehl <code>wp creacaptcha refresh-cloudflare-ips</code>\nbleibt als Deprecation-Alias erhalten (Entfernung frühestens\nv1.0.0).</li>\n<li>WP-CLI: Neuer Diagnose-Befehl\n<code>wp creacaptcha test-bypass</code>, simuliert die Bypass-Auswertung\nmit <code>--ip</code>/<code>--ua</code>/<code>--cookie</code>-Flags.\nExit 0 bei Bypass, Exit 1 sonst.</li>\n<li>WP-CLI: Neuer Diagnose-Befehl <code>wp creacaptcha doctor</code> mit\n9 Pflicht-Checks (Vendored Library, HMAC-Secrets, Event-Log-Tabelle,\nCloudflare-Refresh-Cron, Kill-Switch, Captcha-Plugin-Konflikte,\nPHP-Version, Cloudflare-Cache-Alter, Settings-Defaults). Erweiterbar\nüber den Filter <code>creationell_captcha_doctor_checks</code>.</li>\n<li>WP-CLI: <code>wp creacaptcha status</code> listet jetzt auch die\nfünf neuen Listen mit Eintragszählern.</li>\n<li>Werkzeuge-Seite: Neuer fünfter Block „Cloudflare-IP-Cache” mit\nStatus (gecachte v4/v6-Ranges, letzter Refresh, nächster Cron-Run,\nQuelle) und zwei Buttons („Jetzt aktualisieren”, „Cache leeren”). Beide\nButtons rufen exakt die gleichen Helfer wie die CLI.</li>\n<li>Refactor: Die feldspezifische Validierung für Action-Patterns und\nBypass-Cookies wurde aus\n<code>creationell_captcha_sanitize_settings()</code> in zwei\nwiederverwendbare Helfer extrahiert — Charset-Änderungen sind jetzt an\neiner Stelle gepflegt. Außerdem wurde <code>request_bypassed()</code> in\neine reine <code>evaluate_bypass(?ip, ?ua, cookies)</code> plus dünnen\nGlobals-Wrapper aufgeteilt; alle bestehenden Aufrufer bleiben\nunverändert.</li>\n</ul>\n<h3 id=\"section-19\">0.18.0</h3>\n<ul>\n<li>Interceptor: Drei neue Mechaniken. Die Pfad-Liste\n(<code>Geschützte Pfade</code>) unterstützt jetzt <code>!</code>-Präfix\nfür Ausschluss-Muster (Allow-Liste mit Ausnahmen), z. B.\n<code>/forms/*</code> zusammen mit <code>!/forms/whitelisted</code>.\nEine neue Liste <code>Geschützte Aktionen</code> schützt\nWordPress-Action-Endpoints (das <code>$_POST[action]</code>- oder\n<code>$_GET[action]</code>-Feld auf admin-post.php / admin-ajax.php) —\nselbst wenn diese sonst durch den <code>is_admin()</code>-Bypass\nausgenommen wären. Eine neue Liste <code>Inject-Pfade</code> injiziert\ndie Sicherheitsabfrage automatisch vor jedem <code>&lt;/form&gt;</code>\nder passenden Seiten — nützlich für Theme- oder Drittanbieter-Formulare,\ndie sich nicht direkt modifizieren lassen (idempotent: Formulare mit\nbereits eingebautem Widget werden übersprungen).</li>\n</ul>\n<h3 id=\"section-20\">0.17.0</h3>\n<ul>\n<li>Logging-Granularität: Sechs neue Backend-Checkboxes\n(<code>Erfolgreiche   Verifikationen loggen</code>,\n<code>Fehlgeschlagene Verifikationen loggen</code>,\n<code>Firewall-Blocks loggen</code>,\n<code>Rate-Limit-Blocks loggen</code>,\n<code>Under-Attack-Abfragen loggen</code>,\n<code>Ausgestellte Challenges loggen</code>) steuern, welche\nEreignistypen in den Detail-Event-Log geschrieben werden. Aggregierte\nTages- und Stundenzähler erfassen alle Typen unabhängig davon.\nPer-Default sind die ersten fünf an,\n<code>Ausgestellte Challenges   loggen</code> ist aus\n(hochvolumig).</li>\n<li>Neuer Ereignistyp <code>challenge</code> — wird bei jedem\nREST-Aufruf der Challenge-Route gefeuert. Im Statistik-Dashboard\nerscheint die neue Kachel/Spalte „Challenges ausgestellt”\nautomatisch.</li>\n<li>Request-Body-Fingerabdruck: Optionaler neuer Schalter\n<code>Request-Body-Fingerabdruck speichern</code>. Wenn aktiv, wird pro\nEvent-Log-Zeile eine JSON-Map aus Feldnamen und Wertlängen mit abgelegt\n— ohne die Werte selbst. Hilft bei der Angriffsmuster-Analyse, ohne PII\nzu speichern.</li>\n<li>IP-Anonymisierung: Optionaler neuer Schalter\n<code>IP-Adressen anonymisieren</code> trunkiert IPv4-Adressen auf das\nletzte Oktett und IPv6 auf die letzten 80 Bit, bevor sie in den\nEvent-Log geschrieben werden — DSGVO-konform.</li>\n</ul>\n<h3 id=\"section-21\">0.16.0</h3>\n<ul>\n<li>Bypass: Neue Backend-Sektion „Bypass” im Firewall-Tab mit drei\nEintragsarten, die jeweils Firewall, Rate-Limiter, Captcha und\nUnder-Attack-Modus gleichermaßen umgehen — die bisherige\nIP-Erlaubnisliste (jetzt global), eine User-Agent-Wildcard-Liste und\neine Cookie-Bypass-Liste im Format „name=wert”. Bypass-Treffer auf\nFormular-Ebene erscheinen im Event-Log als <code>verified</code>-Eintrag\nmit passendem Grund (IP-Allowlist / UA-Bypass / Cookie-Bypass).</li>\n<li>Widget: Dritter Anzeigemodus „Schwebendes Overlay” — die\nSicherheits- abfrage erscheint als kleines Pop-up über dem Submit-Button\nund löst beim Submit automatisch.</li>\n</ul>\n<h3 id=\"section-22\">0.15.0</h3>\n<ul>\n<li>Firewall/IP-Erkennung: Der weitergeleitete Header (X-Forwarded-For,\nX-Real-IP, CF-Connecting-IP, True-Client-IP) wird nur noch dann\nbeachtet, wenn die direkte Verbindung aus einem vertrauenswürdigen Hop\nkommt. Neue Sektion „Proxy &amp; IP-Ermittlung” im Firewall-Tab mit\nTextarea für vertrauenswürdige Proxies, Toggles für Private-Netze und\nCloudflare und optionalem täglichem Cron-Refresh der CF-Ranges.\nCloudflare-Snapshot wird mitgeliefert. Die Trust-Liste lässt sich\nzusätzlich über die wp-config-Konstante\n<code>CREATIONELL_CAPTCHA_TRUSTED_PROXIES</code> ergänzen. Bei aktivem\nProxy-Modus ohne konfigurierte Trust-Quelle erscheint im Backend ein\nHinweis. Neuer WP-CLI-Befehl\n<code>wp creacaptcha refresh-cloudflare-ips</code>.</li>\n</ul>\n<h3 id=\"section-23\">0.14.0</h3>\n<ul>\n<li>Statistik: Die Statistik-Seite hat einen „↻ Aktualisieren”-Button.\nDer „Ereignisse”-Tab erfasst je Ereignis zusätzlich Plugin/Integration,\nAktion, Formular-ID, Auslöser-Grund, User-Agent, Referrer, Benutzer-ID\nund die eingereichten Verifizierungsdaten, zeigt eine erweiterte\nSpaltenauswahl und öffnet pro Zeile ein Detail-Fenster mit allen\nerfassten Feldern. Der CSV-Export enthält die neuen Felder.</li>\n</ul>\n<h3 id=\"section-24\">0.13.0</h3>\n<ul>\n<li>WP-CLI: neue Befehlsgruppe <code>wp creacaptcha …</code> für Status,\nDiagnose, Statistik, Einstellungen\n(lesen/setzen/exportieren/importieren/zurücksetzen), Modul-Aktivierung,\nPflege der IP- und User-Agent-Listen, Verwaltung des Event-Logs und eine\nReparatur-Routine.</li>\n<li>Backend: neue Seite <strong>CreaCaptcha → Werkzeuge</strong> zum\nExportieren und Importieren der Einstellungen, für einen vollständigen\nReset auf Werkseinstellungen sowie zum Laden der Standardwerte unter\nBeibehaltung der gepflegten Listen.</li>\n</ul>\n<h3 id=\"section-25\">0.12.0</h3>\n<ul>\n<li>Statistik: Der „Ereignisse”-Tab hat jetzt eine Filter-Leiste —\nFreitextsuche über IP-Adresse und Pfad, Filter nach Ereignistyp und ein\nVon/Bis-Datumsbereich —, blättert seitenweise durch alle aufgezeichneten\nEreignisse und bietet einen CSV-Export der jeweils gefilterten\nEreignismenge zur weiteren Analyse.</li>\n</ul>\n<h3 id=\"section-26\">0.11.0</h3>\n<ul>\n<li>Statistik: Die Statistik-Seite ist jetzt ein Dashboard mit drei Tabs\n(Übersicht, Verlauf, Ereignisse). Der „Übersicht”-Tab zeigt KPI-Kacheln\nfür den 24-Stunden-Blick und eine Vergleichstabelle über vier\nZeitfenster (24 Stunden, 7 Tage, 30 Tage, 90 Tage); ein neuer\nstündlicher Zähler liefert die Daten für das 24-Stunden-Fenster.</li>\n</ul>\n<h3 id=\"section-27\">0.10.0</h3>\n<ul>\n<li>Backend: Die Einstellungsseite ist jetzt in sechs thematische Tabs\ngegliedert (Captcha, Formulare, Firewall, Under-Attack, E-Mail-Schutz,\nAnalytics) statt einer langen Liste — übersichtlicher, mit weiterhin\neinem gemeinsamen „Änderungen speichern” für alle Tabs.</li>\n</ul>\n<h3 id=\"section-28\">0.9.0</h3>\n<ul>\n<li>E-Mail-Schutz: zusätzlicher Ganzseiten-Buffer-Modus, der das gesamte\nSeiten-HTML verarbeitet und damit auch theme-hart-kodierte\n<code>mailto:</code>-Links und Adressen (z. B. in Footer-Templates)\nverschleiert; der Modus ist unter „Einstellungen → CreaCaptcha →\nE-Mail-Schutz” wählbar.</li>\n</ul>\n<h3 id=\"section-29\">0.8.0</h3>\n<ul>\n<li>E-Mail-Obfuskation: <code>mailto:</code>-Links und\nKlartext-E-Mail-Adressen in Inhalten, Auszügen, Text-Widgets und\nKommentaren werden im Seitenquelltext verschleiert und per JavaScript\nerst im Browser wiederhergestellt; ohne JavaScript erscheint ein\nneutraler Platzhalter.</li>\n</ul>\n<h3 id=\"section-30\">0.7.0</h3>\n<ul>\n<li>Analytics &amp; Event-Logging: datenschutzfreundliche aggregierte\nTageszähler je Ereignistyp und ein Statistik-Dashboard; optional ein\ndetaillierter Event-Log (eigene Tabelle, IP-Adressen) mit\nkonfigurierbarer Aufbewahrung.</li>\n</ul>\n<h3 id=\"section-31\">0.6.0</h3>\n<ul>\n<li>Under-Attack-Modus: ein einschaltbarer Notfall-Modus, der jeden\nanonymen Besucher per Interstitial-Proof-of-Work-Abfrage prüft, bevor er\ndie Website erreicht; ein zeitlich begrenzter, signierter Pass-Cookie\nlässt geprüfte Besucher danach frei surfen.</li>\n</ul>\n<h3 id=\"section-32\">0.5.0</h3>\n<ul>\n<li>Firewall &amp; Rate-Limiting: IP-Blockliste/-Erlaubnisliste (inkl.\nCIDR-Bereiche), User-Agent-Blockliste und ein per-IP-Rate-Limiter mit\nwählbarem Wirkungsbereich. Beide laufen als frühe Request-Guards, mit\nProxy-Modus für die Client-IP-Ermittlung.</li>\n</ul>\n<h3 id=\"section-33\">0.4.0</h3>\n<ul>\n<li>Integrationen für Contact Form 7 und Forminator: automatischer\nProof-of-Work-Schutz für die Formulare beider Plugins, mit\n<code>[creationell_captcha]</code>-Platzhalter zur Positionierung und je\neinem Einstellungs-Schalter.</li>\n</ul>\n<h3 id=\"section-34\">0.3.0</h3>\n<ul>\n<li>Interceptor-Modul: generischer serverseitiger Request-Schutz für\neigene Formular-Pfade (<code>*</code>-Wildcards, fail-closed), Shortcode\n<code>[creationell_captcha]</code> und Template-Tag\n<code>creationell_captcha_widget()</code> zum Einbau des Widgets in\nbeliebige Formulare.</li>\n</ul>\n<h3 id=\"section-35\">0.2.0</h3>\n<ul>\n<li>Captcha-Mechanik: Proof-of-Work-Sicherheitsabfrage (PBKDF2/SHA-256\noder Argon2id), Challenge-REST-Endpoint, gebündelte\nALTCHA-Widget-Web-Component, Replay-Schutz und Schutz der vier\nWordPress-Kernformulare.</li>\n</ul>\n<h3 id=\"section-36\">0.1.0</h3>\n<ul>\n<li>Erstes Grundgerüst: Plugin-Bootstrap, Settings-API-Seite, gebündelte\nALTCHA-Bibliothek (Composer + Strauss) und\nSelf-Hosted-GitHub-Updater.</li>\n</ul>\n",
  "banners": {
    "low": "https://creationell-dev.github.io/creationell-captcha/assets/banner-772x250.avif",
    "high": "https://creationell-dev.github.io/creationell-captcha/assets/banner-1544x500.avif"
  },
  "icons": {
    "default": "https://s.w.org/plugins/geopattern-icon/creationell-captcha.svg"
  }
}