Offene Registrierung gegen Bot-Massenanlage absichern
Auf der Testumgebung liefen seit Juli 2026 taeglich 10-20 automatisierte Registrierungen, die zufaellige Namen mit fremden echten E-Mail-Adressen kombinierten - der Server verschickte Vertrags- und Verifikationsmail an Unbeteiligte. Das IP-Rate-Limit griff nicht, weil jede Anfrage ueber eine eigene Rechenzentrums-IP kam. app/spam-guard.php ergaenzt daher Honigtopf, Zeitfalle, eine globale Notbremse ueber alle IPs hinweg und eine MX/A-Pruefung der Mail-Domain. Die ersten drei antworten mit derselben generischen Meldung wie das Rate-Limit, damit die Antwort nicht verraet, welche Huerde angeschlagen hat; Treffer landen im Error-Log. Bewusst ohne Captcha, um keinen Drittanbieter in den Registrierungspfad zu holen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -266,6 +266,42 @@ Stripe-Flow zur Aktualisierung der Zahlungsart. Im Stripe-Dashboard dürfen der
|
||||
zusätzlich freigeschaltet werden; Bestellungen und Kündigungen sollen nur über
|
||||
die dokumentierten Abläufe der Kaffeeliste erfolgen.
|
||||
|
||||
## Schutz der offenen Registrierung
|
||||
|
||||
Ab Juli 2026 liefen auf `testumgebung.kaffeeliste.de` täglich 10–20
|
||||
automatisierte Registrierungen: zufällige Namen kombiniert mit **fremden,
|
||||
echten** E-Mail-Adressen. Der Server verschickte daraufhin Vertrags- und
|
||||
Verifikationsmail an Leute, die nie etwas bestellt hatten — Mail-Bombing
|
||||
über die eigene Domain, auf Kosten der Zustellbarkeit. Das IP-Rate-Limit
|
||||
griff nicht, weil jede Anfrage über eine eigene Rechenzentrums-IP kam.
|
||||
|
||||
`app/spam-guard.php` stellt deshalb vor `register.php`:
|
||||
|
||||
- **Honigtopf** — ein für Menschen unsichtbares Feld (`contact_reference`),
|
||||
das Formular-Bots ausfüllen. Die Positionierung steht bewusst inline und
|
||||
nicht in `public.css`: lädt das Stylesheet einmal nicht, wäre das Feld
|
||||
sonst sichtbar und ein echter Nutzer könnte hineinschreiben.
|
||||
- **Zeitfalle** — mindestens vier Sekunden zwischen Ausliefern und
|
||||
Absenden des Formulars.
|
||||
- **Globale Notbremse** — höchstens 20 Registrierungen pro Stunde über
|
||||
alle IPs hinweg, zusätzlich zum bestehenden Limit von 5 pro IP.
|
||||
- **Domain-Prüfung** — die Mail-Domain muss einen MX- oder A/AAAA-Record
|
||||
haben. Fehlt `checkdnsrr()`, wird durchgelassen: eine kaputte
|
||||
DNS-Auflösung darf keine echten Registrierungen blockieren.
|
||||
|
||||
Honigtopf, Zeitfalle und beide Rate-Limits antworten mit **derselben**
|
||||
generischen Meldung, damit die Antwort nicht verrät, welche Hürde
|
||||
angeschlagen hat. Treffer stehen im PHP-Error-Log (`Spam-Guard: …`) — dort
|
||||
lässt sich ablesen, ob die Maßnahmen greifen. Nur die Domain-Prüfung nennt
|
||||
den Grund, weil das in aller Regel ein Tippfehler eines echten Nutzers ist.
|
||||
|
||||
Bewusst **kein** Captcha: Turnstile oder hCaptcha wären wirksam, holen aber
|
||||
einen Drittanbieter in den Registrierungspfad und damit in die
|
||||
Datenschutzerklärung. Erst wenn die obigen Hürden nachweislich nicht
|
||||
reichen, ist das die nächste Stufe.
|
||||
|
||||
Abgedeckt von `scripts/check-spam-guard.php` (ohne Datenbank lauffähig).
|
||||
|
||||
## Betreiber-Benachrichtigung bei neuer Registrierung
|
||||
|
||||
`register.php` schickt nach einer erfolgreichen Selbstregistrierung einen
|
||||
|
||||
Reference in New Issue
Block a user