- JavaScript 44.1%
- HTML 28.3%
- CSS 20%
- PHP 6.3%
- Shell 0.7%
- Other 0.6%
| assets | ||
| docker | ||
| .gitignore | ||
| CodeRecap.md | ||
| index.html | ||
| LICENSE | ||
| README.md | ||
Capture Barrierefrei
Eine barrierefreie Bot-Erkennungs- und Formularvalidierungslösung mit integrierter Formularerkennung und E-Mail-Versand-System.
Repository: git.nerdtech.info/L_cke_text/captureBarrierefrei
Inhaltsverzeichnis
Einführung
Capture Barrierefrei ist eine Alternative zu herkömmlichen CAPTCHA-Systemen, die barrierefrei gestaltet wurde. Das Projekt bietet ein Grundgerüst für eine agnostische Lösung zum Schutz von Webformularen vor Spam-Bots und automatisierten Angriffen, während es gleichzeitig die Zugänglichkeit für alle Nutzer, einschließlich solcher mit Beeinträchtigungen, gewährleistet.
Projektübersicht
Die Lösung besteht aus zwei Hauptmodulen:
- CaptureBarriereFrei: Erkennt automatisierte Bot-Zugriffe durch Verhaltensanalyse
- MailSender: Verarbeitet Formularübermittlungen und E-Mail-Versand mit Templateunterstützung
Beide Module sind so konzipiert, dass sie den Prinzipien der Barrierefreiheit entsprechen und mit Screenreadern sowie anderen assistiven Technologien kompatibel sind.
Architektur
Dateistruktur
├── assets/
│ ├── js/
│ │ ├── captureBarriereFrei/ # Bot-Erkennungs-Modul
│ │ │ ├── index.js # Einstiegspunkt, exposes window.CaptureBarriereFrei
│ │ │ ├── core.js # Kernfunktionalität
│ │ │ ├── botDetection.js # Bot-Erkennungslogik
│ │ │ ├── formProtection.js # Formularschutz
│ │ │ ├── formValidation.js # Validierungsfunktionen
│ │ │ ├── ui.js # UI-Komponenten + injizierte Styles (Dark/Light)
│ │ │ ├── utils.js # Hilfsfunktionen
│ │ │ └── logger.js # Logging-Funktionalität
│ │ └── mailSender/ # E-Mail-Versand-Modul
│ │ ├── index.js # Einstiegspunkt, exposes window.MailSender
│ │ ├── core/ # Kernfunktionalität
│ │ └── utils/ # Hilfsfunktionen
│ ├── config/
│ │ ├── config.js # Zentrale Konfiguration (window.FormularKonfiguration)
│ │ └── betreff-routing.json # Subject-Dropdown + per-Subject Empfänger-Routing
│ ├── css/
│ │ ├── style.css # Design System (Dark/Light, Akkordeon, Theme-Toggle)
│ │ └── form-styles.css # Portables Basis-Stylesheet (nicht anfassen)
│ ├── php/
│ │ ├── send_mail.php # Backend-Handler für POST-Anfragen
│ │ └── mail_diagnose.php # Debug-Helper (nicht für Produktion)
│ └── templates/
│ ├── contact.html # Benachrichtigungs-Mail an Seitenbetreiber
│ └── confirmation.html # Bestätigungs-Mail an Nutzer
└── index.html # Showcase mit Akkordeon-Anleitung und Theme-Toggle
docker/
├── Dockerfile # php:8.2-apache + msmtp (Build-Kontext: Repo-Root)
├── docker-compose.yml # Traefik-Labels, HTTPS, Security-Headers
├── entrypoint.sh # Schreibt /etc/msmtprc zur Laufzeit
└── .env.example # SMTP-Vorlage (nie committen)
Sicherheitskonzept
Das Sicherheitskonzept basiert auf einem mehrstufigen Ansatz — kein einzelner Mechanismus, sondern eine Kombination aus:
- Verhaltensanalyse – Mausbewegungen, Tastatureingaben, Scrollverhalten
- Honeypot-Felder – für Menschen unsichtbare Fallen, die Bots typischerweise befüllen
- Zeitanalyse – zu schnelles Ausfüllen deutet auf Automatisierung hin
- Punkte-basiertes Scoring – erst ab Score ≥ 40 wird der Submit freigegeben
- Human-Verification-Checkbox – faktisch Pflicht, da der Score ohne sie max. 32 erreicht
- Server-seitige Empfänger-Whitelist – verhindert, dass direkter POST-Zugriff beliebige Empfänger einschleust
Technischer Deep-Dive zu Score-Berechnung, Ladeablauf, Submit-Pfad und Template-Engine: → CodeRecap.md
Barrierefreiheit
Capture Barrierefrei wurde mit Fokus auf Zugänglichkeit entwickelt (WCAG 2.1 AA):
- Tastaturzugänglichkeit: Alle Funktionen sind vollständig per Tastatur bedienbar — inkl. der CAPTCHA-Checkbox (Tab → Space)
- Screenreader-Unterstützung: ARIA-Attribute und semantisches HTML
- Skip-Links:
<a href="#main-content" class="skip-link">+<main tabindex="-1">(WCAG 2.4.1) - Farben und Kontraste: Ausreichende Kontrastverhältnisse im Dark- und Light-Mode
- Fehlerfeedback: Klare, zugängliche Fehlermeldungen mit
aria-describedby - Fokus-Management: JS-gestützte Fokusindikatoren (
.cbf-focused) und logische Tab-Reihenfolge; keine.preventDefault()blockiert natives Tastaturverhalten - Theme-neutral: Sowohl Dark- als auch Light-Mode erfüllen die Kontrastanforderungen
Pflichtattribute die nicht entfernt werden dürfen:
<select name="betreff">brauchtaria-required="true"undaria-invalid="false"- Jedes Eingabefeld braucht ein
<label>und einaria-describedby-Fehlerelement
Installationsanleitung
-
Dateien kopieren — folgende Ordner und Dateien ins Zielprojekt übernehmen (Struktur beibehalten):
assets/js/captureBarriereFrei/ assets/js/mailSender/ assets/config/config.js assets/config/betreff-routing.json assets/css/form-styles.css assets/php/send_mail.php assets/templates/contact.html assets/templates/confirmation.htmlNicht kopieren:
assets/php/mail_diagnose.php,assets/templates/helper.js,index.html(Showcase) -
Skripte einbinden — Reihenfolge in
<body>einhalten (Module vor Config):<!-- Module zuerst (laden asynchron) --> <script type="module" src="assets/js/captureBarriereFrei/index.js"></script> <script type="module" src="assets/js/mailSender/index.js"></script> <!-- Konfiguration zuletzt (nutzt window.CaptureBarriereFrei + window.MailSender) --> <script src="assets/config/config.js"></script> <script> document.addEventListener('DOMContentLoaded', function () { window.FormularKonfiguration.initialisiere(); }); </script> -
Formular vorbereiten:
<form id="kontaktFormular" method="post" class="protected" data-template="kontakt"> <!-- Formularfelder --> </form>class="protected"aktiviert den automatischen Bot-Schutz.data-templategibt an, welche Template-Konfiguration ausconfig.jsverwendet wird. Der<select name="betreff">wird dynamisch ausbetreff-routing.jsonbefüllt — keine<option>-Elemente manuell eintragen. -
PHP-Backend einrichten: Sicherstellen, dass
send_mail.phpauf dem Server PHPmail()oder SMTP nutzen kann. Mitmail_diagnose.phplässt sich die Serverkonfiguration prüfen (danach vom Server entfernen). -
Theme-Switch (optional): Das
<html>-Element trägt immer entwederdata-theme="dark"oderdata-theme="light"— nie keines von beidem. Das aktive Theme wird inlocalStorageuntercbf-themegespeichert. Ohne gespeicherten Wert folgt der Switch der Systempräferenz (prefers-color-scheme).FOUC-Prevention im
<head>(vor dem ersten<style>):<script> (function () { var stored = localStorage.getItem('cbf-theme'); var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; var theme = stored || (prefersDark ? 'dark' : 'light'); document.documentElement.setAttribute('data-theme', theme); })(); </script>Alle CSS Custom Properties in
style.csssowie die perensureStyles()injizierten Checkbox-Styles inui.jsreagieren auf dieses Attribut.
Konfiguration
Die Hauptkonfiguration erfolgt in assets/config/config.js:
window.FormularKonfiguration = {
empfaenger: 'ihre-email@domain.de',
betreff: 'Neue Nachricht vom Kontaktformular',
endpoint: 'assets/php/send_mail.php',
thresholdScore: 40, // Bot-Score-Schwellenwert (Standard: 40)
DEBUGGING: false, // true = verbose console logging
// ...weitere Einstellungen für Templates, Dateiuploads etc.
};
Das Subject-Dropdown und das Empfänger-Routing werden in assets/config/betreff-routing.json gepflegt:
[
{ "wert": "anfrage", "bezeichnung": "Allgemeine Anfrage", "empfaenger": "info@domain.de" },
{ "wert": "support", "bezeichnung": "Support", "empfaenger": "support@domain.de" }
]
E-Mail-Zustellbarkeit
Damit Kontaktanfragen sicher ankommen und nicht im Spam landen, sind ein paar einfache Einstellungen auf dem Mailserver und in der Domain notwendig. Das klingt technischer als es ist – die meisten Hoster bieten dafür fertige Assistenten im Control Panel an.
Domain-Einstellungen (empfohlen)
| Maßnahme | Was es tut | Priorität |
|---|---|---|
| SPF-Record | Erlaubt deinem Server, E-Mails für deine Domain zu senden – verhindert Spoofing | Hoch |
| DKIM-Signatur | Digitale Unterschrift, die beweist, dass die Mail wirklich von dir kommt | Hoch |
| DMARC-Record | Gibt Mailservern an, wie mit Mails umzugehen ist, die SPF/DKIM nicht bestehen | Mittel |
Beispiel-DNS-Einträge (Werte bei deinem Hoster anpassen):
# SPF – erlaube deinem Mailserver (IP oder Hostname anpassen)
TXT @ "v=spf1 mx a include:dein-mailserver.de ~all"
# DMARC – optionale Benachrichtigungs-Mail anpassen
TXT _dmarc "v=DMARC1; p=quarantine; rua=mailto:dmarc@deinedomain.de"
Den DKIM-Key generiert dein Mailserver (z. B. Postfix + OpenDKIM) – der öffentliche Schlüssel kommt dann als TXT-Record in die DNS-Zone.
Absenderadresse (SMTP_FROM)
Die Absenderadresse in docker/.env sollte auf derselben Domain liegen wie die Website:
# Gut – Domain stimmt überein, SPF/DKIM greifen
SMTP_FROM=kontakt@deinedomain.de
# Problematisch – fremde Domain, hohe Spam-Wahrscheinlichkeit
SMTP_FROM=irgendwas@gmail.com
Hinweis für Empfänger: Wenn du Kontaktanfragen auf eine persönliche Adresse weiterleitest, füge die Absenderadresse (
SMTP_FROM) zum Adressbuch deines Mailprogramms hinzu. Viele Spam-Filter lernen daraus und stufen künftige Mails korrekt ein.
Warum landen Mails trotzdem im Spam?
Häufige Ursachen und Lösungen:
- Kein SPF/DKIM → DNS-Records wie oben beschrieben einrichten
From-Header ≠ Absenderdomain →SMTP_FROMund Mailserver-Domain angleichen- Shared-Hosting-IP auf Sperrliste → IP-Reputation bei MXToolbox prüfen; ggf. dedizierten Mailserver nutzen
- Kein Reverse-DNS (PTR-Record) → Beim Hoster einen PTR-Record für die Server-IP einrichten lassen
- Neue Domain / neue IP → E-Mail-Verkehr langsam aufbauen ("Warm-up"), nicht sofort viele Mails senden
Schnelltest nach dem Deployment
mail_diagnose.php ist durch ein Secret-Token geschützt und funktioniert auf Shared Hosting und Docker gleichermaßen – keine Serverkonfiguration nötig.
Einmalig: Token setzen
Öffne assets/php/mail_diagnose.php und ersetze BITTE_AENDERN durch einen eigenen zufälligen String:
# Zufälliges Token generieren (Linux/macOS)
openssl rand -hex 16
// assets/php/mail_diagnose.php – Zeile ~13
define('DIAGNOSE_TOKEN', 'dein-generiertes-token-hier');
Aufruf im Browser:
https://deinedomain.de/assets/php/mail_diagnose.php?token=dein-generiertes-token-hier
Docker (alternativ direkt im Container):
docker exec -it <container-name> curl "localhost/assets/php/mail_diagnose.php?token=dein-token"
Nach der Diagnose: Token zurücksetzen (
BITTE_AENDERN) oder Datei vom Server entfernen.
Nutzungsbeispiele
Einfache Implementierung:
<form id="kontaktFormular" class="protected" data-template="kontakt">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" required aria-describedby="name-error">
<span id="name-error" class="error-message" aria-live="polite"></span>
</div>
<div class="form-group">
<label for="email">E-Mail</label>
<input type="email" id="email" name="email" required aria-describedby="email-error">
<span id="email-error" class="error-message" aria-live="polite"></span>
</div>
<div class="form-group">
<label for="nachricht">Nachricht</label>
<textarea id="nachricht" name="nachricht" required aria-describedby="nachricht-error"></textarea>
<span id="nachricht-error" class="error-message" aria-live="polite"></span>
</div>
<button type="submit">Absenden</button>
</form>
Benutzerdefinierte Konfiguration:
const captureConfig = {
formSelectors: '#meinFormular',
minTimeToFill: 5000, // 5 Sekunden
thresholdScore: 50 // Höherer Schwellenwert für mehr Sicherheit
};
const mailConfig = {
recipient: 'team@domain.de',
subject: 'Kontaktanfrage Website',
endpoint: 'mein-handler.php'
};
const captureInstance = new CaptureBarriereFrei(captureConfig);
const mailSender = new MailSender(mailConfig);
Dev-Server starten (Pflicht — file:// bricht fetch() für JSON/Templates/PHP):
# Python (im Projektordner)
python3 -m http.server 8080
# Dann im Browser öffnen:
# http://localhost:8080
Showcase
index.html ist die interaktive Demo-Seite des Projekts. Sie zeigt alle Features live im Browser — kein Build-Schritt nötig.
Was die Showcase-Seite enthält:
- Live-Kontaktformular mit aktivem Bot-Schutz, Human-Verification-Checkbox und barrierefreier Validierung
- Feature-Cards (12 Stück, 6 davon hinter „Mehr anzeigen"): Überblick über alle Kernfunktionen
- Dark/Light-Mode-Toggle mit FOUC-Prevention und
localStorage-Persistenz - Responsive Burger-Navigation (Breakpoint 768 px) mit Full-Screen-Overlay, Focus-Trap und Escape-Key-Unterstützung
- Akkordeon-Anleitung mit Schritt-für-Schritt-Installationshinweisen
- DSGVO-Abschnitt mit Erläuterungen zu Art. 25 (Privacy by Design) und Art. 32 (TLS/HTTPS)
Showcase lokal starten:
# Im Projektordner
python3 -m http.server 8080
# → http://localhost:8080
file://ist nicht ausreichend —fetch()für JSON-Routing und HTML-Templates erfordert HTTP.
Docker-Deployment
Das docker/-Verzeichnis enthält alles für den produktiven Betrieb hinter einem Traefik-Reverse-Proxy mit automatischem Let's-Encrypt-Zertifikat.
docker/
├── Dockerfile ← php:8.2-apache + msmtp (Build-Kontext: Repo-Root)
├── docker-compose.yml ← Traefik-Labels, HTTPS, Security-Headers (alle Domains/Namen via ENV)
├── entrypoint.sh ← Schreibt /etc/msmtprc zur Laufzeit
└── .env.example ← Vorlage für alle Variablen (nie committen)
Einmaliges Setup:
# 1. .env aus der Vorlage anlegen und Werte eintragen
cp docker/.env.example docker/.env
# Pflichtfelder in docker/.env:
# APP_NAME – Container-Name + Traefik-Bezeichner (z. B. myapp)
# APP_DOMAIN – Öffentliche Domain (z. B. example.com)
# SMTP_HOST – Mailserver-Hostname
# SMTP_PORT – 587 (STARTTLS) oder 465 (SSL)
# SMTP_FROM – Absenderadresse
# SMTP_USER – SMTP-Benutzername
# SMTP_PASSWORD – SMTP-Passwort
# 2. Container bauen und starten (vom Repo-Root aus)
docker compose -f docker/docker-compose.yml up -d --build
Einmaliges Setup:
# 1. .env aus der Vorlage anlegen und Werte eintragen
cp docker/.env.example docker/.env
# → SMTP_HOST, SMTP_PORT, SMTP_FROM, SMTP_USER, SMTP_PASSWORD setzen
# 2. Container bauen und starten (vom Repo-Root aus)
docker compose -f docker/docker-compose.yml up -d --build
Sicherheitshinweise:
docker/.envist in.gitignoreeingetragen und landet niemals im Repository.entrypoint.shschreibt/etc/msmtprcerst beim Containerstart aus den ENV-Variablen — keine Credentials im Image-Layer.- Das Dockerfile entfernt
docker/,README.md,AGENTS.mdund.gitignoreaus dem Web-Root, sodass nur die Anwendungsdateien unter/var/www/html/erreichbar sind.
Voraussetzungen auf dem Host:
- Docker + Docker Compose v2
- Laufender Traefik-Container im externen Netzwerk
traefik-publicmit konfiguriertemletsencrypt-Certresolver - DNS-Eintrag für
allyform.jpboehm.dezeigt auf den Host
TODO und Überlegungen
- Umgebungsvariablen /
.env-Support für Serverkonfiguration - PHP-Payload in Base64 zur Verschleierung sensibler Daten
- Dynamische, nichtlineare Score-Berechnung (Jitter, Interaktionsdichte):
function scoreMausbewegung(bewegungen) { if (bewegungen === 0) return 0; if (bewegungen < 5) return 2; if (bewegungen < 15) return 6; return 10; } - Erweiterte Verhaltensanalyse: Tipp-Rhythmus, Pause-Muster, Scroll-Jitter
Lizenz
Dieses Projekt steht unter der MIT-Lizenz. Siehe LICENSE für Details.