~/blog/public-internal-cooperation-platformPOSTED
von Shady Nathan Tawfik · 25. Juli 2026 · 3 min

Eine Plattform für interne Kommunikation, im Internet exponiert

Eine öffentliche Kooperations- und Beratungsplattform betrieb ein Content-System mit drei niedrigen Befunden. Die Lehre steckte darin, was ein niedriger Befund Ihnen nicht sagt.

Interaktiv[blog-2.0]

TL;DR: Drei niedrige Befunde auf einer gepflegten Plattform klingen nach bestanden. Ich erkläre, warum ein niedriger Befund nur eine Aussage über meine gewählten Vektoren ist, und wo die nächste Bewertung beginnen sollte.

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 regionale Kooperations- und Beratungsplattform auf einem gepflegten Enterprise-Content-System hinter einem Reverse Proxy mit aktueller PHP-Laufzeit. Geprüft wurden Versionsstatus, Header-Policy, Informationsfreigabe und die exponierte 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:

Ein niedriger Befund ist eine Aussage über die gewählten Vektoren, nicht über das System. Drei niedrige Befunde auf einer gepflegten Plattform bedeuten meist, dass die Plattform aktuell ist, der Pluginsatz klein ist und die interessante Fläche hinter etwas liegt.

Der Grund, dieses Mandat aufzuschreiben, ist die Form der Landschaft. Eine Kooperationsplattform verwaltet Termine, Beratungsanfragen und interne Mitteilungen. Das Content-System ist nur die Auslieferungsschicht, aber das Datenmodell unterscheidet anonyme Leser von authentifizierten Teilnehmenden, und diese Unterscheidung liegt in Routing und Session statt im Content.

Die konkrete Lehre betrifft die Reihenfolge. Header-, Versions- und Freigabe-Fixes sind billig, sofort und dauerhaft geplant. Session- und Autorisierungsdesign ist teuer.

TL;DR: Eine öffentliche Kooperations- und Beratungsplattform betrieb ein Content-System mit drei niedrigen Befunden. Die Lehre steckte darin, was ein niedriger Befund Ihnen nicht sagt.

Befunde

SchweregradBefundNachweis
NIEDRIGSicherheits-Header auf der öffentlichen Oberfläche fehlenKein Frame-, Referrer- oder Content-Type-Schutz
NIEDRIGContent-System-Version in Asset-PfadenGenaues Release identifizierbar
NIEDRIGKeine veröffentlichte SicherheitskontaktdateiKein Kanal für koordiniertes Melden
INFOPlattform und Laufzeit aktuellKeine bekannte Schwachstelle im Kernsystem
INFOAdministrative Pfade eingeschränktKein beschreibbarer Endpunkt anonym erreichbar
INFOKeine reflektierte Eingabe in öffentlichen FormularenKein ausnutzbarer Injektionspunkt gefunden

Der Angriffspfad

Public visitorContent system delivery layerAuthenticated participantSession and routing layerCooperation platform functionsAppointments and counselling requestsData model boundary not covered by this assessment

Reproduktion im Labor

Jeder Befehl unten zielt auf einen Lab-Container, den ich selbst kontrolliere. Nichts davon ist auf ein laufendes System gerichtet.

Die Ausgangsbasis auf der eigenen Plattform erheben

~/code/bash bash
$ for h in example.org; do
    printf '%s\n' "$h"
    curl -sI "https://$h/" | grep -iE 'strict-transport|content-security-policy|x-frame|x-content-type|referrer-policy|permissions-policy' || echo '  keine Sicherheits-Header'
    curl -s "https://$h/" | grep -oiE 'generator[^>]*content="[^"]+"' | head -3
    curl -so /dev/null -w '  security.txt -> %{http_code}\n' "https://$h/.well-known/security.txt"
  done

Erkennung in eigener Infrastruktur

Prüfen, ob anonyme und authentifizierte Fläche sich unterscheiden

~/code/bash bash
# derselbe Pfad vor und nach einer Sitzung sollte sich im Verhalten unterscheiden, nicht im Bestehen
$ curl -so /dev/null -w 'anonym    %{http_code}\n' https://example.org/termine
$ curl -so /dev/null -w 'mit-cookie %{http_code}\n' \
  -H 'Cookie: session=<eigene-testsitzung>' https://example.org/termine

# was eine vollständige Sitzung erreicht, was anonym nicht erreichbar ist
$ curl -s https://example.org/ | grep -oE 'href="/[a-z0-9/-]*"' | sort -u | head -20

Behebung

Die Header-Baseline einmalig in der Plattformkonfiguration ausliefern

~/code/nginx nginx
# Basislinie für jede Antwort der Landschaft
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'self'; base-uri 'self'" always;
server_tokens off;

Eine Sicherheitskontaktdatei veröffentlichen

~/code/text text
# .well-known/security.txt
Contact: mailto:security@example.org
Expires: 2027-12-31T23:59:59.000Z
Preferred-Languages: en, de
Canonical: https://example.org/.well-known/security.txt
Policy: https://example.org/security-policy

Fazit — was ich daraus mitnehme

  • Niedrige Schwere bedeutet, dass Ihre Vektorliste kurz war, nicht dass das System sicher ist.
  • Content-Systeme sind die Auslieferungsschicht; Autorisierung liegt eine Ebene tiefer.
  • Beheben Sie Header- und Versionshygiene zuerst, weil sie den Boden dauerhaft heben.
  • Schreiben Sie hin, was die Bewertung nicht abgedeckt hat, damit die nächste dort beginnt.

Nur zu Bildungszwecken. Alle reproduzierbaren Befehle zielen auf meine eigene Lab-Umgebung (localhost), nie auf ein laufendes System. © 2026