TL;DR: Das statische Frontend war sauber; die Serverless-Funktionsebene dahinter nicht. Ich habe Origin-Handling, Rate-Limits und die Mail-Kette getestet und erkläre, warum Plattform-Standards driften.
Ausgangslage
Ich habe das Ziel als Black-Box geprüft: keine Zugangsdaten, nur die öffentlich sichtbare Fläche. Das ist, was ich sah, bevor ich etwas angefasst habe.
Eine Marketing- und Lead-Generation-Site auf einem gehosteten Site-Builder, ausgeliefert über ein Content Delivery Network mit Serverless-Funktionen für Formularverarbeitung. Geprüft wurden Edge-Konfiguration, Funktionsfreigabe, Formularverarbeitung, E-Mail-Authentifizierung und Verwaltungsoberfläche.
Ich habe alle identifizierenden Informationen entfernt. Das Ziel wird ausschließlich nach Branche und Technologieklasse beschrieben, damit das Muster übertragbar bleibt.
Das Muster
Das Muster, das ich erkannt habe — und das ich in ähnlichen Landschaften immer wieder finde:
Der Site-Builder-Markt erzeugt eine spezifische Architektur: vorgerenderte Seiten aus einem visuellen Editor, ein Content Delivery Network davor und wenige Serverless-Funktionen für die Teile, die nicht statisch sein können. Kontaktformulare, Gutscheinprüfung und Authentifizierung liegen in dieser letzten Gruppe.
Statische Seiten sind wirklich schwer anzu greifen. Es gibt keinen Interpreter im Request-Pfad. Die Funktionen sind wieder interessant, und sie sind meist der am schlechtesten dokumentierte Teil des Deployments, weil sie entstanden sind, damit ein Formular funktioniert, und nie als Anwendung behandelt wurden.
Das zweite wiederkehrende Thema: Plattformverwaltete Sites erben Standardwerte, die niemand gewählt hat. E-Mail-Authentifizierung, Sicherheits-Header und Subdomain-Policy werden bei der Einrichtung einmal gesetzt und driften danach.
Befunde
| Schweregrad | Befund | Nachweis |
|---|---|---|
| HOCH | Funktions-Endpunkt ohne Origin-Prüfung aufrufbar | Akzeptiert Cross-Origin-Formularposts by Design |
| MITTEL | Kein Rate-Limit auf der Formularfunktion | Unbegrenzte Einsendungen an einen Mail-Versand-Endpunkt |
| MITTEL | E-Mail-Authentifizierung fehlt für die Absenderdomain | Fälschbare ausgehende E-Mails |
| MITTEL | Plattform-Vorschaumgebung indexiert | Entwurfsinhalte öffentlich erreichbar |
| NIEDRIG | Framework-Banner auf Funktionsantworten | Laufzeit- und Plattformversion identifizierbar |
| NIEDRIG | Subdomain-Policy zu permissiv | Wildcard-Einträge für Asset-Hosts |
Der Angriffspfad
Reproduktion im Labor
Jeder Befehl unten zielt auf einen Lab-Container, den ich selbst kontrolliere. Nichts davon ist auf ein laufendes System gerichtet.
Den eigenen Funktions-Endpunkt auf Origin- und Rate-Verhalten prüfen
# Ziel: Ihre eigene deployte Funktion
$ curl -s -o /dev/null -w '%{http_code}\n' 'https://example.org/api/contact'
# interessiert sie sich für die Herkunft der Anfrage
$ curl -s -o /dev/null -w '%{http_code}\n' -X POST \
-H 'Origin: https://evil.example' -H 'Content-Type: application/json' \
-d '{"email":"a@b.example"}' 'https://example.org/api/contact'
# und ist sie ratenbegrenzt
$ for i in $(seq 1 12); do
curl -so /dev/null -w '%{http_code} ' -X POST -H 'Content-Type: application/json' \
-d "{\"n\":$i}" 'https://example.org/api/contact'
done; echo
Erkennung in eigener Infrastruktur
Funktionen hinter einer statischen Front-End-Seite inventarisieren
$ curl -s https://example.org/ | grep -oiE '(href|src|action)="[^"]+"' \
| grep -iE 'api|form|submit|action|endpoint' | sort -u
# der Formular-Endpunkt des Builders ist oft derselbe
$ curl -s https://example.org/ | grep -oiE 'data-[a-z-]*(endpoint|form|action)="[^"]+"' | sort -u
Die E-Mail-Authentifizierungskette der Absenderdomain verifizieren
$ dig +short TXT example.org | grep -i spf
$ dig +short TXT _dmarc.example.org
$ dig +short TXT selector1._domainkey.example.org | head
Behebung
Origin an der Edge validieren und ratenbegrenzen, bevor die Funktion läuft
# Formularpfad ratenbegrenzen, pro Client
limit_req_zone $binary_remote_addr zone=forms:10m rate=5r/m;
location = /api/contact {
limit_req zone=forms burst=3 nodelay;
limit_req_status 429;
if ($http_origin !~* '^https://(www\.)?example\.org$') {
return 403;
}
proxy_pass http://functions;
}
Explizite, erzwungene E-Mail-Authentifizierung setzen
# SPF: genau die Versanddienste autorisieren, dann hart ablehnen
v=spf1 include:<sending-provider> -all
# DMARC: mit Monitoring beginnen, auf Quarantäne, dann ablehnen
v=DMARC1; p=none; rua=mailto:dmarc-reports@example.org; fo=1
# nach zwei sauberen Reporting-Zyklen:
# v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.org
# nach vier:
# v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.org
Sobald ein Angreifer Zugriff hat, kann er folgende Aktionen durchführen:
Fazit — was ich daraus mitnehme
- Ein statisches Front End bedeutet keine statische Landschaft.
- Funktionen, die ein Formular zum Laufen bringen, brauchen ein echtes Code-Review.
- Rate-Limits gehören an die Edge, wo das CDN jede Anfrage bereits sieht.
- Plattform-Defaults driften; E-Mail- und Subdomain-Policy brauchen einen Verantwortlichen.