TL;DR: Zwei Generationen einer Plattform auf einer Domain: die moderne war aktuell, die Legacy-Instanz definierte das Risiko, und der Parent-Cookie-Scope verband beide. Ich zeige, wie ich beide Landschaften kartiert habe und wie man das Archiv abschaltet.
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 Community- und Veranstaltungsplattform mit aktuellem Content-Management-System auf der Hauptdomain und einer Legacy-Installation desselben Plattformsystems für einen archivierten Bereich auf einer Subdomain, davor ein Caching-Layer. Geprüft wurden beide Landschaften, der gemeinsame Cookie-Scope, Client-Bibliotheksversionen und Subdomain-Freigabe.
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:
Nebeneinander laufende Generationen sind normal, und dort wird technische Schulde zur Angriffsfläche. Wenn eine aktuelle Plattform die Seite bedient und eine Legacy-Plattform ein Archiv, sind beide erreichbar, teilen eine Domain und erhalten Anfragen desselben Publikums. Die Legacy-Instanz hat keine Betreuer, keinen Patch-Takt und eine kleinere Nutzerbasis, die einen Einbruch bemerkt.
Zwei Verstärker: erstens der Cache, der alte Plattformen vor einer oberflächlichen Prüfung verbirgt, sodass die Landschaft für alle aktuell aussieht. Zweitens der Cookie-Scope, denn ein Cookie auf der Elterndomain wird an jeden Host darunter gesendet.
Der dritte Verstärker ist die Client-Bibliothek. Lange tote Plattformen liefern tote Bibliotheken, die andere Seiten weiter nutzen. Eine ungepflegte Installation ist daher auch ein Supply-Chain-Problem.
Befunde
| Schweregrad | Befund | Nachweis |
|---|---|---|
| HOCH | Legacy-Plattform weiterhin auf einer Subdomain ausgeliefert | Archivbereich auf einer Version jenseits des Supports |
| HOCH | Client-Bibliotheksversion jenseits des Supports | Betrifft Drittseiten, die die Abhängigkeit nicht gewählt haben |
| MITTEL | Cookie-Scope über beide Plattformen geteilt | Sitzung vom Legacy-Host gilt auf dem modernen Host |
| MITTEL | Caching-Layer verbirgt die Legacy-Plattform | Landschaft wirkt auf automatisierte Prüfungen aktuell |
| NIEDRIG | Enumerierte Subdomains mit unterschiedlichen Stacks | Mehrere Technologien auf einer Domain |
| NIEDRIG | Administrative Pfade auf beiden Landschaften erreichbar | Gleichmäßige Angriffsfläche statt eines gehärteten Punkts |
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.
Die Generationen in der eigenen Landschaft kartieren
# was antwortet wo, einschliesslich Archivbereichen
$ for h in example.org www.example.org archive.example.org old.example.org legacy.example.org; do
printf '%-28s %s %s\n' "$h" \
"$(curl -so /dev/null -w '%{http_code}' https://$h/)" \
"$(curl -sI https://$h/ | grep -i '^x-powered-by\|^x-generator\|^server:' | head -1 | tr -d '\r')"
done
# wird das Eltern-Cookie geteilt
$ curl -sI https://example.org/ | grep -i '^set-cookie'
Erkennung in eigener Infrastruktur
Prüfen, welche eigenen Client-Bibliotheken das Supportende erreicht haben
$ npm outdated --json 2>/dev/null | python3 -c '
import json,sys
d = json.load(sys.stdin)
for name, info in d.items():
cur, want = info.get("current"), info.get("wanted")
print(f"{name}: {cur} -> {want}")' | head -30
# und jeden Host auflisten, den Sie wirklich besitzen
$ for h in $(cat hosts.txt); do
printf '%s %s\n' "$h" "$(dig +short "$h" | tr '\n' ' ')"
done
Behebung
Das Sitzungs-Cookie auf den Host einschränken, der es braucht
# kein Sitzungs-Cookie für die gesamte Landschaft
proxy_cookie_path / /;
proxy_cookie_domain example.org ~^([a-z0-9-]+\.)?example\.org$ localhost;
# besser: Host-only setzen, indem kein Domain-Attribut gesetzt wird
add_header Set-Cookie "sessionid=; Path=/; Secure; HttpOnly; SameSite=Lax" always;
Sobald ein Angreifer Zugriff hat, kann er folgende Aktionen durchführen:
Fazit — was ich daraus mitnehme
- Zwei Generationen auf einer Domain bedeuten zwei Angriffsflächen und einen Cookie-Scope.
- Ein Cache, der eine alte Plattform verbirgt, verbirgt sie auch vor Ihren eigenen Audits.
- Eine ungepflegte Plattform ist ein Abhängigkeitsproblem für Dritte, nicht nur Ihres.
- Ziehen Sie das Archiv per Redirect zurück; jedes laufende Jahr ist ein Jahr Exposition.