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>
Neuer Helfer app/pushover.php meldet Selbstregistrierungen an den
Betreiber. Der Aufruf sitzt in register.php statt in
saas_register_tenant_owner(), damit die check-*-Skripte keine Pushes
ausloesen, und wertet das Ergebnis nicht aus: ein fehlgeschlagener Push
darf die Registrierung nicht abbrechen. Ohne PUSHOVER_TOKEN/PUSHOVER_USER
ist die Funktion still deaktiviert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vor dem ersten Abruf soll klar sein, ob der Host das Postfach ueberhaupt
erreicht - und auf welchem Weg. Das Skript meldet PHP-Version, ob die
imap-Erweiterung geladen ist, ob die PAYPAL_*-Einstellungen gesetzt sind,
und oeffnet das Postfach testweise ueber eine reine TLS-Verbindung.
Damit ist auch ohne die Erweiterung belegbar, dass ein Abruf moeglich
waere - seit PHP 8.4 ist imap kein Bestandteil von PHP mehr und laesst
sich auf einem Webhosting nicht einfach nachruesten.
Bewusst nur lesend: EXAMINE statt SELECT, kein Flag wird gesetzt. Das
Passwort wird nie ausgegeben, nur seine Laenge als Tippfehler-Probe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Mail-Verarbeitung ignorierte bisher die PayPal-Schalter: eingehende
Zahlungen wurden auch dann automatisch gutgeschrieben, wenn der Betreiber
die Funktion gesperrt oder der Mandant PayPal abgeschaltet hatte. Jetzt
wird die Zahlung in dem Fall geparkt - gespeichert, aber ohne Buchung.
Wegwerfen liesse eine echte Zahlung unbemerkt verschwinden, buchen
widersprache der Abschaltung; die Zuordnungsseite bleibt fuer offene
Zahlungen ja erreichbar.
--dry-run war bisher irrefuehrend: es liess die Verarbeitung samt Buchung
laufen und uebersprang nur das Setzen des Gelesen-Flags - ausgerechnet beim
ersten Testlauf haette es also echtes Geld verbucht. Der Probelauf nutzt
jetzt paypal_preview(), das nichts schreibt und meldet, was passieren
wuerde (would_book/would_queue/would_park/duplicate).
scripts/check-paypal-inbox-flow.php deckt die Kette ohne IMAP ab:
Absenderpruefung, Token, Parser, Zuordnung, Netto-Buchung, Dedup, beide
Park-Faelle und die Schreibfreiheit der Vorschau.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vor dem ersten FTP-Deploy nach /testumgebung.kaffeeliste.de/httpdocs/
fehlte jede Absicherung des Upload-Umfangs: sync_config.jsonc hatte eine
leere excludePath-Liste, es waeren also .git (komplett herunterladbar),
.env.local (Dev-DB-Zugangsdaten) und sync_config.jsonc selbst (enthaelt
das FTP-Passwort im Klartext) mit ausgeliefert worden. Von diesen dreien
war keines von den bestehenden .htaccess-Regeln erfasst.
- sync_config.jsonc: excludePath gefuellt; scripts/ und database/ bleiben
bewusst im Deploy, weil die Plesk-Scheduled-Tasks sie vom Webspace aus
ausfuehren.
- .htaccess: sync_config.jsonc und Dotfile-Ordner gesperrt, Vendor-
Verzeichnisse (TCPDF/PHPMailer/DataTables) fuer direkte URL-Aufrufe
gesperrt, HTTPS-Redirect ergaenzt (ohne ihn bekam ein http-Besucher
eine Session ohne secure-Flag).
- PHPMailer/ entfernt: enthielt nur noch LICENSE, composer.json und ein
per URL erreichbares get_oauth_token.php, kein Quellcode. Der Versand
laeuft seit M6 ueber saas_send_mail().
- docs/deployment.md: Umgebungen, Deploy-Ablauf, Migrationen und
Cron-Jobs ueber Plesk Scheduled Tasks (kein SSH verfuegbar),
Mail-/DNS-, Stripe- und PayPal-Voraussetzungen, Go-Live-Checkliste.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>