No description
  • JavaScript 44.1%
  • HTML 28.3%
  • CSS 20%
  • PHP 6.3%
  • Shell 0.7%
  • Other 0.6%
Find a file
2026-05-07 18:16:21 +02:00
assets feat: verbessere Formatierung und Struktur der mail_diagnose.php für bessere Lesbarkeit und Benutzerfreundlichkeit 2026-05-07 16:32:54 +02:00
docker feat: ändere Dienstnamen in docker-compose.yml von ${APP_NAME} zu capturebarrierefreiheit 2026-05-07 18:16:21 +02:00
.gitignore feat: Enhance project structure and add Docker support 2026-05-07 16:03:18 +02:00
CodeRecap.md feat: aktualisiere CodeRecap.md mit neuen Abschnitten zur Tastaturzugänglichkeit und E-Mail-Template-Engine; überarbeite README.md für bessere Struktur und Klarheit 2026-05-07 17:55:59 +02:00
index.html feat: Enhance project structure and add Docker support 2026-05-07 16:03:18 +02:00
LICENSE Remove copyright notice from LICENSE 2025-10-20 23:21:33 +02:00
README.md feat: aktualisiere CodeRecap.md mit neuen Abschnitten zur Tastaturzugänglichkeit und E-Mail-Template-Engine; überarbeite README.md für bessere Struktur und Klarheit 2026-05-07 17:55:59 +02:00

Capture Barrierefrei

Eine barrierefreie Bot-Erkennungs- und Formularvalidierungslösung mit integrierter Formularerkennung und E-Mail-Versand-System.

Version License WCAG

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:

  1. CaptureBarriereFrei: Erkennt automatisierte Bot-Zugriffe durch Verhaltensanalyse
  2. 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):

  1. Tastaturzugänglichkeit: Alle Funktionen sind vollständig per Tastatur bedienbar — inkl. der CAPTCHA-Checkbox (Tab → Space)
  2. Screenreader-Unterstützung: ARIA-Attribute und semantisches HTML
  3. Skip-Links: <a href="#main-content" class="skip-link"> + <main tabindex="-1"> (WCAG 2.4.1)
  4. Farben und Kontraste: Ausreichende Kontrastverhältnisse im Dark- und Light-Mode
  5. Fehlerfeedback: Klare, zugängliche Fehlermeldungen mit aria-describedby
  6. Fokus-Management: JS-gestützte Fokusindikatoren (.cbf-focused) und logische Tab-Reihenfolge; kein e.preventDefault() blockiert natives Tastaturverhalten
  7. Theme-neutral: Sowohl Dark- als auch Light-Mode erfüllen die Kontrastanforderungen

Pflichtattribute die nicht entfernt werden dürfen:

  • <select name="betreff"> braucht aria-required="true" und aria-invalid="false"
  • Jedes Eingabefeld braucht ein <label> und ein aria-describedby-Fehlerelement

Installationsanleitung

  1. 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.html
    

    Nicht kopieren: assets/php/mail_diagnose.php, assets/templates/helper.js, index.html (Showcase)

  2. 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>
    
  3. Formular vorbereiten:

    <form id="kontaktFormular" method="post" class="protected" data-template="kontakt">
      <!-- Formularfelder -->
    </form>
    

    class="protected" aktiviert den automatischen Bot-Schutz. data-template gibt an, welche Template-Konfiguration aus config.js verwendet wird. Der <select name="betreff"> wird dynamisch aus betreff-routing.json befüllt — keine <option>-Elemente manuell eintragen.

  4. PHP-Backend einrichten: Sicherstellen, dass send_mail.php auf dem Server PHP mail() oder SMTP nutzen kann. Mit mail_diagnose.php lässt sich die Serverkonfiguration prüfen (danach vom Server entfernen).

  5. Theme-Switch (optional): Das <html>-Element trägt immer entweder data-theme="dark" oder data-theme="light" — nie keines von beidem. Das aktive Theme wird in localStorage unter cbf-theme gespeichert. 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.css sowie die per ensureStyles() injizierten Checkbox-Styles in ui.js reagieren 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:

  1. Kein SPF/DKIM → DNS-Records wie oben beschrieben einrichten
  2. From-Header ≠ Absenderdomain → SMTP_FROM und Mailserver-Domain angleichen
  3. Shared-Hosting-IP auf Sperrliste → IP-Reputation bei MXToolbox prüfen; ggf. dedizierten Mailserver nutzen
  4. Kein Reverse-DNS (PTR-Record) → Beim Hoster einen PTR-Record für die Server-IP einrichten lassen
  5. 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/.env ist in .gitignore eingetragen und landet niemals im Repository.
  • entrypoint.sh schreibt /etc/msmtprc erst beim Containerstart aus den ENV-Variablen — keine Credentials im Image-Layer.
  • Das Dockerfile entfernt docker/, README.md, AGENTS.md und .gitignore aus 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-public mit konfiguriertem letsencrypt-Certresolver
  • DNS-Eintrag für allyform.jpboehm.de zeigt 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.