DNS RobotDNS Propagation Checker
StartDNSWHOISIPSSL
DNS RobotDNS Propagation Checker

DNS-Propagation-Checker der nächsten Generation

DatenschutzrichtlinieNutzungsbedingungenÜber unsBlogKontakt

DNS-Tools

DNS-AbfrageDNS-GeschwindigkeitstestDomain zu IPNS-AbfrageMX-AbfrageAlle anzeigen

E-Mail-Tools

SPF-Eintrag-CheckerDMARC-CheckerDKIM-CheckerSMTP-Test-ToolE-Mail-Header-AnalyseAlle anzeigen

Website-Tools

WHOIS-AbfrageHosting-CheckerDomain-VerfügbarkeitSubdomain-FinderCMS-ErkennungAlle anzeigen

Netzwerk-Tools

Ping-ToolTraceroutePort-CheckerHTTP-Header-CheckSSL-Zertifikat-CheckAlle anzeigen

IP-Tools

IP-AbfrageMeine IP-AdresseIP-Blacklist-CheckIP zu HostnameASN-AbfrageAlle anzeigen

Hilfs-Tools

QR-Code-ScannerQR-Code-GeneratorUPI QR Code GeneratorWiFi QR Code GeneratorMorsecode-ÜbersetzerAlle anzeigen
© 2026 DNS Robot. Entwickelt von: ❤ Shaik Brothers
Alle Systeme betriebsbereit
Made with
Startseite/Blog/Website-Sicherheit: Best Practices Schicht für Schicht (2026)

Website-Sicherheit: Best Practices Schicht für Schicht (2026)

Shaik Vahid29. Sept. 202630 Min. Lesezeit
Website-Sicherheit Best Practices als sechs Schichten: Domain und DNS, TLS, HTTP-Header, Anwendung, Abhängigkeiten, Server
Website-Sicherheit Best Practices als sechs Schichten: Domain und DNS, TLS, HTTP-Header, Anwendung, Abhängigkeiten, Server

Kernaussage

Website-Sicherheit nach Best Practices funktioniert in Schichten: Sichern Sie Domain und DNS ab (Registrar Lock, DNSSEC, CAA), erzwingen Sie modernes TLS mit HSTS, senden Sie einen strikten Satz an HTTP-Sicherheitsheadern, hashen Sie Passwörter mit Argon2id und schützen Sie Logins mit MFA und Rate Limiting, validieren Sie Eingaben und setzen Sie die Zugriffskontrolle auf dem Server durch, pinnen und prüfen Sie Abhängigkeiten, schließen Sie jeden Port, den Sie nicht bedienen, und protokollieren Sie genug, um einen Einbruch zu bemerken. Zu jeder Maßnahme unten finden Sie die genaue Konfiguration und einen kostenlosen Weg, um zu prüfen, ob sie wirklich greift – denn eine Schutzmaßnahme, die Sie nie getestet haben, ist eine, die Sie nicht haben.

Advertisement

Website-Sicherheit: Was Best Practices wirklich bedeuten

Website-Sicherheit nach Best Practices umfasst alle Maßnahmen, die verhindern, dass eine Website oder Webanwendung übernommen, verunstaltet, als Angriffswerkzeug gegen die eigenen Besucher missbraucht oder unbemerkt ihrer Daten beraubt wird. Das ist weder ein einzelnes Produkt noch eine einzelne Einstellung, sondern ein Stapel von Entscheidungen: Er beginnt beim Domain-Registrar und reicht über DNS, TLS, die HTTP-Header Ihres Servers, den Code für Logins und Eingaben, die Drittanbieter-Pakete, auf denen Sie aufbauen, und den Server selbst bis zu den Logs, die Ihnen zeigen, dass etwas schiefgelaufen ist.

In Schichten zu denken lohnt sich, weil Angreifer genau das tun. Laut Verizons 2026 Data Breach Investigations Report beginnen 31 % aller Datenpannen inzwischen mit einer ausgenutzten Software-Schwachstelle – damit liegt dieser Einstiegsweg erstmals vor gestohlenen Zugangsdaten –, und 48 % aller Datenpannen gehen mit Ransomware einher. Ein einziger fehlender Patch, ein geleakter API-Schlüssel oder eine Admin-Seite ohne Rate Limiting genügt. Keine der Maßnahmen in diesem Leitfaden ist exotisch; gehackt werden meist die Websites, die auf einer Schicht die Grundlagen ausgelassen und eine andere auf Hochglanz poliert haben.

Dieser Leitfaden arbeitet sich von außen nach innen vor. Zu jeder Maßnahme erfahren Sie, warum sie wichtig ist, was genau Sie konfigurieren müssen und wie Sie sie überprüfen – per Befehl oder mit einem kostenlosen Tool. Denn der häufigste Fehler, den wir bei HTTP-Header-Checks und SSL-Checks sehen, ist keine schlechte Entscheidung, sondern eine Einstellung, von der jemand glaubte, sie sei aktiv, und die nie überprüft wurde.

Hinweis

Wenn Sie nur eine Stunde Zeit haben: Aktivieren Sie Registrar Lock und MFA bei Ihrem Registrar, erzwingen Sie HTTPS mit HSTS, ergänzen Sie die Sicherheitsheader aus der Tabelle in Schicht 3, hashen Sie Passwörter mit Argon2id, aktualisieren Sie jede Abhängigkeit mit bekannter CVE und schließen Sie alle Ports außer 80 und 443. Damit decken Sie die Einfallstore ab, über die die große Mehrheit realer Angriffe auf Websites läuft.

Der Web-Security-Stack: Sechs Schichten, die Sie schützen müssen

Jeder Angriff auf eine Website trifft eine von sechs Schichten. Die folgende Tabelle ist die Landkarte für den Rest dieses Leitfadens: was auf jeder Schicht liegt, wie sie typischerweise angegriffen wird und mit welchem kostenlosen Test Sie bestätigen, dass Ihre Abwehr tatsächlich greift.

SchichtWas Angreifer hier tunZentrale MaßnahmenPrüfen mit
1. Domain und DNSDomain kapern, Nameserver ändern, verwaiste Subdomains übernehmen, gefälschte Zertifikate ausstellen lassenRegistrar Lock, MFA, DNSSEC, CAA, Prüfung veralteter EinträgeWHOIS-Abfrage, DNS-Lookup, Subdomain-Finder
2. Transport (TLS)Herabstufung auf HTTP, Verschlüsselung aushebeln, alte Cipher ausnutzen, abgelaufene ZertifikateTLS 1.2+, HSTS mit Preload, automatische ErneuerungSSL-Checker
3. HTTP-HeaderSkripte einschleusen (XSS), die Seite für Clickjacking in Frames einbetten, Content-Types erraten lassen, Referrer preisgebenCSP, frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicyHTTP-Header-Checker
4. AnwendungCredential Stuffing, Injection, fehlerhafte Zugriffskontrolle, CSRF, unsichere UploadsArgon2id + MFA + Rate Limits, parametrisierte Abfragen, serverseitige Autorisierung, SameSite-CookiesCode-Review, OWASP ZAP, Passwort-Stärke-Test
5. AbhängigkeitenVergiftete Pakete, bekannte CVEs in Bibliotheken, kompromittierte CI-PipelinesLockfiles, Audits, gepinnte Versionen, SBOM, Tokens mit minimalen Rechtennpm audit, Dependabot, Trivy
6. Server und BetriebOffene Ports, Standard-Zugangsdaten, fehlende Patches, keine Backups, keine LogsFirewall, SSH nur mit Schlüssel, Patching, 3-2-1-Backups, zentrales LoggingPort-Checker, IP-Blacklist-Checker, Domain-Health-Check

Tipp

Arbeiten Sie von oben nach unten. Die Schichten 1 bis 3 sind Konfiguration, die Sie an einem Nachmittag erledigen können, und sie schützen jede Seite auf einmal. Die Schichten 4 bis 6 sind dauerhafte Gewohnheiten, die in Ihrem Code-Review- und Deployment-Prozess verankert sein müssen.

Advertisement

Schicht 1: Domain und DNS absichern

Alles Weitere in diesem Leitfaden setzt voraus, dass Sie Ihre Domain noch kontrollieren. Kann sich ein Angreifer bei Ihrem Registrar anmelden oder Ihre Nameserver ändern, leitet er Ihren Traffic beliebig um, erhält ein gültiges Zertifikat für Ihren Namen und liest jede E-Mail an Sie mit – ohne dass Ihr Anwendungscode jemals ausgeführt wird. Die Sicherheit von Domain und DNS ist deshalb die erste Best Practice der Websicherheit, und sie besteht fast ausschließlich aus Konfiguration.

Beginnen Sie mit einer WHOIS-Abfrage Ihrer eigenen Domain und prüfen Sie drei Dinge: Die Statuscodes enthalten clientTransferProhibited, das Ablaufdatum liegt mehr als ein Jahr in der Zukunft, und der Registrar ist einer, bei dem Sie tatsächlich ein Konto haben. Erstaunlich oft liegt die Domain eines Unternehmens noch im Registrar-Konto eines ehemaligen Dienstleisters. Unser Leitfaden zur WHOIS-Abfrage erklärt jeden Statuscode, der Ihnen begegnen kann.

Registrar Lock, MFA und Ablaufwarnungen

Aktivieren Sie den Registrar Lock (auch Transfer-Sperre genannt), damit die Domain nicht zu einem anderen Registrar umgezogen werden kann, ohne dass Sie sie ausdrücklich entsperren, und schalten Sie Multi-Faktor-Authentifizierung für das Registrar-Konto selbst ein. Registrar-Konten sind ein beliebtes Phishing-Ziel, gerade weil ein einziger Login alles Nachgelagerte kontrolliert. Nutzen Sie einen Hardware-Schlüssel oder eine Authenticator-App statt SMS, wo immer der Registrar das zulässt.

Stellen Sie die Domain auf automatische Verlängerung mit einem Zahlungsmittel, das nicht abläuft, und legen Sie trotzdem 60 Tage vor dem Ablaufdatum eine Kalendererinnerung an. Abgelaufene Domains schnappen sich Drop-Catcher innerhalb von Stunden, und der Käufer erbt Ihre E-Mails, Ihren Traffic und alle OAuth-Logins, die Ihrer Domain vertrauen.

  • Registry Lock (eine manuelle Sperre auf Registry-Ebene, die außerhalb des normalen Kontos gesetzt wird) ist für eine geschäftskritische Domain die Zusatzgebühr wert: Selbst ein kompromittiertes Registrar-Konto kann dann die Nameserver nicht mehr ändern.

  • Trennen Sie die Rollen. Wer die Domain bezahlt, welches Konto sie besitzt und wer der DNS-Anbieter ist, sollte jeweils dokumentiert sein und nicht am Postfach eines einzelnen Mitarbeiters hängen.

  • Aktivieren Sie WHOIS-Privacy, damit Ihre Kontaktdaten keine Vorlage für Phishing liefern, und hinterlegen Sie im Konto eine überwachte Rollenadresse wie domains@.

Die Zone mit DNSSEC signieren

DNSSEC signiert Ihre DNS-Zone, damit ein Resolver gefälschte Antworten erkennen kann. Ohne DNSSEC kann ein Angreifer, der den Cache eines Resolvers vergiftet, Ihre Besucher auf einen gefälschten Server schicken, während deren Browser weiterhin Ihren Domainnamen anzeigt. Die meisten verwalteten DNS-Anbieter (Cloudflare, Route 53, Google Cloud DNS und viele Registrare) aktivieren es mit einem Schalter; der einzige manuelle Schritt ist das Hinterlegen des DS-Eintrags bei Ihrem Registrar. Prüfen Sie es mit dig oder mit dem DNSSEC-Test im Domain-Health-Check:

bash
dig +dnssec +short yourdomain.com A
# A signed zone returns the record AND an RRSIG line:
# 203.0.113.10
# A 13 2 3600 20261015000000 20260924000000 34505 yourdomain.com. Kx3f...==

dig +short yourdomain.com DS
# A DS record at the parent zone proves the chain of trust is complete
# 34505 13 2 6A1B...C9

Zertifikatsausstellung mit CAA einschränken

Ein CAA-Eintrag (RFC 8659) legt fest, welche Zertifizierungsstellen Zertifikate für Ihre Domain ausstellen dürfen. Jede öffentliche CA muss ihn vor der Ausstellung prüfen – ein CAA-Eintrag sperrt also einen Angreifer aus, der die Domain-Validierung einer anderen CA ausgetrickst hat. Drei Einträge decken die üblichen Fälle ab: wer ausstellen darf, wer Wildcards ausstellen darf und wohin abgelehnte Anfragen gemeldet werden:

dns
yourdomain.com.  CAA 0 issue "letsencrypt.org"
yourdomain.com.  CAA 0 issuewild ";"
yourdomain.com.  CAA 0 iodef "mailto:security@yourdomain.com"

Warnung

Listen Sie vor dem Anlegen von CAA jede CA auf, die derzeit Zertifikate für Sie ausstellt – auch die hinter Ihrem CDN oder Hosting-Panel (Cloudflare wechselt zwischen mehreren CAs; viele Hoster nutzen Sectigo oder Let's Encrypt). Ein CAA-Eintrag, der Ihre tatsächliche CA auslässt, lässt die nächste Erneuerung stillschweigend scheitern. Prüfen Sie den aktuellen Aussteller vorher mit dem SSL-Checker.

Veraltete Einträge prüfen: Subdomain Takeover

Ein Subdomain Takeover passiert, wenn ein DNS-Eintrag noch auf einen Dienst zeigt, den Sie nicht mehr nutzen: ein CNAME auf eine gelöschte GitHub-Pages-Seite, eine Azure-App, einen S3-Bucket oder den Hostnamen eines SaaS-Anbieters. Jeder kann das verwaiste Ziel registrieren und dann unter Ihrem Namen Inhalte auf old-app.yourdomain.com ausliefern – samt gültigem Zertifikat. Es ist einer der häufigsten Funde in Bug-Bounty-Programmen, weil sich niemand mehr an den Eintrag erinnert.

Prüfen Sie Ihre Domain mit dem Subdomain-Finder, der Certificate-Transparency-Logs auswertet – so sehen Sie jeden Hostnamen, für den jemals ein Zertifikat ausgestellt wurde. Lösen Sie dann jeden davon per DNS-Lookup auf und löschen Sie jeden Eintrag, dessen Ziel NXDOMAIN oder die „no such app“-Seite eines Anbieters liefert. Wiederholen Sie das vierteljährlich, und machen Sie das Löschen des DNS-Eintrags zum festen Bestandteil jeder Stilllegung eines Dienstes.

Tipp

Certificate Transparency ist zugleich Ihr Frühwarnsystem: Cert Spotter und das CT-Monitoring von Cloudflare können Sie per E-Mail benachrichtigen, sobald irgendeine CA ein Zertifikat für Ihre Domain ausstellt. Ein unerwartetes Zertifikat ist oft das erste sichtbare Anzeichen dafür, dass DNS oder Registrar kompromittiert wurden.

Schicht 2: HTTPS und TLS richtig umsetzen

HTTPS ist keine Best Practice mehr, sondern die Grundvoraussetzung – Browser markieren reine HTTP-Seiten als „Nicht sicher“. Was eine sichere Website heute noch von einer lediglich verschlüsselten unterscheidet, sind die akzeptierten TLS-Versionen, die Frage, ob HTTP überhaupt noch zu Ihnen führen kann, und ob die Erneuerung so gut automatisiert ist, dass sie die im März 2026 begonnenen Kürzungen der Zertifikatslaufzeit übersteht.

Advertisement

Mindestens TLS 1.2, bevorzugt TLS 1.3

TLS 1.0 und 1.1 wurden 2021 mit RFC 8996 offiziell für veraltet erklärt, und kein aktueller Browser handelt sie noch aus. Deaktivieren Sie sie auf dem Server, bevorzugen Sie TLS 1.3 (das jeden als schwach bekannten Cipher streicht und den Handshake in einem einzigen Roundtrip abschließt) und behalten Sie TLS 1.2 nur mit AEAD-Cipher-Suites wie ECDHE-ECDSA-AES128-GCM-SHA256 oder ECDHE-RSA-CHACHA20-POLY1305 bei.

Beim Test von außen zählen zwei Zeilen: das ausgehandelte Protokoll und Verify return code: 0, was bedeutet, dass die vollständige Zertifikatskette validiert wurde. Ein fehlendes Zwischenzertifikat ist die häufigste Ursache für Meldungen nach dem Muster „funktioniert in Chrome, scheitert in curl und auf Android“; unser Leitfaden zur SSL-Zertifikatskette zeigt, wie Sie das beheben, und der SSL-Checker meldet eine unvollständige Kette direkt. Hier der Test gegen dnsrobot.net:

bash
echo | openssl s_client -connect dnsrobot.net:443 -servername dnsrobot.net 2>/dev/null \
  | grep -E 'Protocol|Cipher|Verify return'

# Protocol  : TLSv1.3
# Cipher    : TLS_AES_256_GCM_SHA384
# Verify return code: 0 (ok)

# Confirm the old versions are refused:
openssl s_client -connect dnsrobot.net:443 -tls1_1 2>&1 | grep -iE 'alert|no protocols'

Hinweis

In Cipher-Listen veralten kopierte Konfigurationen am schnellsten. Statt sie von Hand zu schreiben, erzeugen Sie den aktuell empfohlenen Server-Block für nginx, Apache, Caddy oder HAProxy mit dem Mozilla SSL Configuration Generator und wählen das Profil „Intermediate“, sofern Sie nicht sehr alte Clients unterstützen müssen.

HSTS: Nie wieder HTTP im Browser

Eine Weiterleitung von HTTP auf HTTPS allein reicht nicht. Die allererste Anfrage eines Besuchers an http://yourdomain.com geht weiterhin im Klartext über die Leitung, und ein Angreifer im selben Netzwerk kann sie beantworten, bevor Ihre Weiterleitung greift. HTTP Strict Transport Security (RFC 6797) behebt das: Sobald ein Browser den Header einmal gesehen hat, schreibt er jede künftige http://-URL Ihrer Domain in https:// um, bevor er überhaupt etwas sendet.

Setzen Sie max-age auf mindestens ein Jahr (31536000 Sekunden), ergänzen Sie includeSubDomains, sobald jede Subdomain HTTPS ausliefert, und tragen Sie die Domain dann auf hstspreload.org ein, damit sie fest in Chrome, Firefox, Safari und Edge eingebaut wird. Das Preloading schließt die Lücke beim ersten Besuch vollständig. Prüfen Sie den Header mit dem HTTP-Header-Checker, der HSTS als Teil seiner Sicherheitsnote von A bis F bewertet.

http
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Warnung

HSTS ist eine Einbahnstraße. Sobald includeSubDomains im Preload steht, wird jede Subdomain, die kein gültiges HTTPS ausliefern kann – auch interne Tools und ein vergessener dev.-Host –, im Browser unerreichbar. Führen Sie es stufenweise ein: max-age=300 für eine Woche, dann einen Monat, dann ein Jahr, und ergänzen Sie erst danach preload.

47-Tage-Zertifikate: Automatisieren Sie die Erneuerung jetzt

Das CA/Browser Forum verkürzt mit dem Ballot SC-081 die maximale Laufzeit jedes öffentlichen TLS-Zertifikats schrittweise. Die erste Stufe trat am 15. März 2026 in Kraft: Jedes Zertifikat, das Sie heute kaufen oder erneuern, ist bereits auf 200 Tage begrenzt, und ab 2029 muss ein Zertifikat etwa alle sechs Wochen ersetzt werden:

StichtagMaximale ZertifikatslaufzeitWiederverwendung der Domain-Validierung
Vor dem 15. März 2026398 Tage398 Tage
15. März 2026200 Tage200 Tage
15. März 2027100 Tage100 Tage
15. März 202947 Tage10 Tage

Manuelle Erneuerung hält diesem Zeitplan nicht stand. Best Practice ist die vollautomatische Ausstellung über ACME: Let's Encrypt oder Google Trust Services per certbot, acme.sh oder Caddy, oder die automatischen Zertifikate von Cloudflare, Vercel, Netlify und den meisten Hosting-Panels. Testen Sie den Erneuerungsweg, bevor Sie ihn brauchen (certbot renew --dry-run bei certbot); die typische Stolperfalle ist ein seit der letzten Erneuerung hinzugefügter CAA-Eintrag oder eine neue Firewall-Regel, die nun die Validierung blockiert. Egal, was Sie einsetzen: Überwachen Sie das Ablaufdatum auch von außen – der SSL-Checker zeigt die verbleibenden Tage, und ein abgelaufenes Zertifikat verwandelt jeden Besuch in eine ganzseitige Browserwarnung.

Schicht 3: HTTP-Sicherheitsheader

Sicherheitsheader sind Anweisungen Ihres Servers an den Browser, was er mit Ihren Seiten tun darf und was nicht: welche Skripte laufen dürfen, ob die Seite in einen Frame eingebettet werden darf, ob der Browser Content-Types raten darf und was er anderen Websites darüber verrät, woher ein Besucher kam. Sie kosten nichts, gelten für alle Seiten zugleich und blockieren ganze Angriffsklassen. Gleichzeitig ist es die Schicht, die die meisten Websites teilweise falsch umsetzen – deshalb bewertet der HTTP-Header-Checker sie. Das sendet dnsrobot.net, gekürzt auf die Sicherheitsheader:

bash
curl -sI https://dnsrobot.net/ | grep -iE 'strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy'

strict-transport-security: max-age=31536000; includeSubDomains; preload
content-security-policy: default-src 'self'; script-src 'self' ... https://*.googletagmanager.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(self), microphone=(), geolocation=(), payment=(), usb=()

Die sieben Header, die jede Website senden sollte

Das sind die Zielwerte für eine typische Website. Die ersten fünf verbessern Ihre Bewertung; die letzten beiden sind günstige Ergänzungen, sobald die anderen stehen.

HeaderEmpfohlener WertWas er verhindert
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preloadProtokoll-Downgrade, Cookie-Diebstahl über HTTP
Content-Security-PolicyNonce-basiertes script-src mit 'strict-dynamic'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'Cross-Site-Scripting (XSS), Dateninjektion, Clickjacking
X-Content-Type-OptionsnosniffMIME-Sniffing, das einen Upload in ausführbares Skript verwandelt
Referrer-Policystrict-origin-when-cross-originPreisgabe vollständiger URLs (Tokens, Suchbegriffe) an Dritte
Permissions-Policycamera=(), microphone=(), geolocation=(), payment=()Drittanbieter-Skripte, die unbemerkt mächtige Browser-APIs nutzen
X-Frame-OptionsDENY (Legacy-Fallback für frame-ancestors)Clickjacking in Browsern ohne CSP Level 2
Cross-Origin-Opener-Policysame-originFensterübergreifende Angriffe über window.opener

Content Security Policy einführen, ohne die Website lahmzulegen

Eine Content Security Policy ist die wirksamste Einzelmaßnahme gegen XSS, weil sie eingeschleuste Skripte selbst dann an der Ausführung hindert, wenn eine Injection-Lücke existiert. Der Haken: Eine strikte Policy bricht jedes Inline-Skript und jedes Drittanbieter-Tag, das Sie vergessen haben. Der moderne Ansatz, von Google empfohlen und auf MDN dokumentiert, ist eine Nonce-basierte Policy: Der Server erzeugt pro Antwort eine zufällige Nonce, setzt sie in jedes Script-Tag, das er bewusst ausgibt, und der Browser verweigert alles andere.

'strict-dynamic' macht die Policy praxistauglich: Ein Skript mit Nonce darf weitere Skripte nachladen (Analytics, Tag-Manager, Widgets), ohne dass jedes einzeln freigegeben werden muss, während moderne Browser die Tokens https: und 'unsafe-inline' ignorieren – sie dienen nur als Fallback für alte Browser. Führen Sie die Policy zuerst mit Content-Security-Policy-Report-Only ein, beobachten Sie eine Woche lang die Verstoßberichte und schalten Sie dann auf Durchsetzung um. Frameworks wie Next.js, Rails und Django unterstützen Nonces von Haus aus; statische Websites können stattdessen ein Hash-basiertes script-src verwenden.

http
Content-Security-Policy:
  script-src 'nonce-r4nd0m1z3dV4lu3' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';
  frame-ancestors 'none';
  form-action 'self';
  report-to csp-endpoint

<!-- Only scripts carrying the nonce run; strict-dynamic lets them load their own dependencies -->
<script nonce="r4nd0m1z3dV4lu3" src="/app.js"></script>

Hinweis

Eine Allowlist-Policy wie script-src 'self' https://cdn.example.com ist besser als nichts, doch jeder JSONP-Endpunkt und jede alte Bibliothek auf einem freigegebenen Host lässt sich zu ihrer Umgehung nutzen. Wenn Sie noch keine Nonces einsetzen können, setzen Sie zumindest object-src 'none' und base-uri 'none' – das schließt sofort zwei gängige Umgehungswege.

Clickjacking: frame-ancestors und X-Frame-Options

Beim Clickjacking wird Ihre Website unsichtbar in die Seite eines Angreifers geladen, und der Besucher wird dazu gebracht, auf einen Button zu klicken, den er nicht sieht. frame-ancestors 'none' in der CSP (oder 'self', wenn Sie eigene Seiten einbetten) verhindert das in allen aktuellen Browsern, X-Frame-Options: DENY deckt ältere ab. Bieten Sie bewusst ein einbettbares Widget an, nehmen Sie nur diesen Pfad aus – und nur für die Origins, die ihn brauchen. Unser Leitfaden zu X-Frame-Options zeigt die genauen Serverregeln und die „refused to connect“-Fehler, auf die Sie beim Testen stoßen werden.

nosniff, Referrer-Policy, Permissions-Policy und COOP

X-Content-Type-Options: nosniff hindert den Browser daran, einen Content-Type eigenmächtig anders zu deuten – genau das macht aus einem hochgeladenen „Bild“ mit HTML-Inhalt eine ausführbare Seite. Referrer-Policy: strict-origin-when-cross-origin (Standard in aktuellen Browsern, aber setzen Sie es explizit) sendet nur Ihren Origin an andere Websites, sodass Passwort-Reset-Tokens und Suchanfragen in URLs privat bleiben. Permissions-Policy deaktiviert Browserfunktionen, die Sie nicht nutzen, damit ein kompromittiertes Drittanbieter-Skript weder die Kamera öffnen noch den Standort auslesen kann. Cross-Origin-Opener-Policy: same-origin kappt die window.opener-Verbindung zu Seiten, die Sie öffnen, und blockiert damit eine Klasse fensterübergreifender Angriffe.

Auch Header, die Sie entfernen sollten, sind wichtig: Server und X-Powered-By verraten Schwachstellenscannern die genauen Softwareversionen, und X-XSS-Protection ist veraltet und kann in alten Browsern Fehler verursachen – setzen Sie ihn auf 0 oder lassen Sie ihn weg. Der CMS-Detector zeigt, was ein Scanner allein aus den Headern über Ihren Stack erfährt.

Tipp

Setzen Sie Header einmal zentral am Edge (CDN, Reverse Proxy oder Framework-Middleware) statt pro Seite. In Next.js ist das die Proxy- oder Middleware-Datei, in nginx ein add_header-Block im Server-Kontext, in Apache Header always set. Führen Sie den HTTP-Header-Checker anschließend nach jedem Deployment erneut aus, denn eine neue Framework-Version oder CDN-Einstellung kann stillschweigend einen Header verlieren.

Schicht 4: Authentifizierung, die Credential Stuffing standhält

Angreifer raten Passwörter selten einzeln. Sie spielen Milliarden von E-Mail-Passwort-Paaren ab, die bei anderen Websites geleakt wurden (Credential Stuffing), und phishen den Rest. Best Practices für die Authentifizierung haben daher drei Teile: Passwörter so speichern, dass ein Datenbank-Leak kein Passwort-Leak ist, ein gestohlenes Passwort allein nutzlos machen und Brute Force so verlangsamen, dass es keine Rolle spielt. OWASP führt Authentication Failures in den OWASP Top 10:2025 auf Platz A07.

Advertisement

Passwörter mit Argon2id oder bcrypt hashen

Speichern Sie niemals ein Passwort – und niemals einen schnellen Hash davon. MD5, SHA-1 und selbst SHA-256 sind auf Geschwindigkeit ausgelegt, sodass eine geleakte Tabelle solcher Hashes auf einer einzigen GPU mit Milliarden Versuchen pro Sekunde getestet werden kann. Verwenden Sie eine langsame, speicherintensive Passwort-Hashing-Funktion mit individuellem Salt pro Passwort. Das OWASP Password Storage Cheat Sheet empfiehlt in dieser Reihenfolge:

  • Argon2id mit mindestens 19 MiB Speicher, 2 Iterationen und Parallelitätsgrad 1 (oder 46 MiB mit 1 Iteration).

  • scrypt mit N = 2^17, r = 8, p = 1, wo Argon2 nicht verfügbar ist.

  • bcrypt mit einem Work Factor von 10 oder höher (beachten Sie die Eingabegrenze von 72 Byte; das Vorab-Hashen längerer Passwörter erfordert Sorgfalt).

  • PBKDF2-HMAC-SHA256 mit 600.000 Iterationen nur dort, wo FIPS-Konformität es erzwingt.

javascript
// Node.js with the argon2 package
import argon2 from "argon2";

const hash = await argon2.hash(password, {
  type: argon2.argon2id,
  memoryCost: 19456, // KiB = 19 MiB
  timeCost: 2,
  parallelism: 1,
});

// Later, on login:
const ok = await argon2.verify(hash, submittedPassword);

Hinweis

Stimmen Sie die Kosten so ab, dass ein Hash auf Ihrem Login-Server etwa 100 bis 250 ms dauert. Für echte Nutzer ist das unmerklich, begrenzt einen Angreifer aber auf wenige Tausend Versuche pro Sekunde und Kern statt auf Milliarden. Hashen Sie bei erfolgreichem Login neu, wann immer Sie die Parameter erhöhen – so aktualisieren sich alte Hashes von selbst.

Passwortregeln, die wirklich helfen (NIST SP 800-63B)

Die Kompositionsregeln, die die meisten Websites noch erzwingen (ein Großbuchstabe, ein Sonderzeichen, Wechsel alle 90 Tage), führen zu vorhersehbaren Passwörtern wie Summer2026! und verleiten Menschen dazu, sie wiederzuverwenden. Die aktuelle Richtlinie NIST SP 800-63B ersetzt sie durch Regeln, die messen, worauf es ankommt:

  • Mindestens 8 Zeichen, wenn zusätzlich MFA verlangt wird, und mindestens 15 Zeichen für ein Passwort, das allein verwendet wird; erlauben Sie mindestens 64.

  • Keine Kompositionsregeln und kein erzwungener regelmäßiger Wechsel; verlangen Sie eine Änderung nur bei Hinweisen auf eine Kompromittierung.

  • Prüfen Sie jedes neue Passwort gegen eine Liste geleakter Passwörter (mit der Range-API von Have I Been Pwned geht das, ohne das Passwort zu übermitteln) und lehnen Sie bekannte ab.

  • Erlauben Sie Einfügen und Passwort-Manager, akzeptieren Sie Leerzeichen und Unicode, und zeigen Sie eine Stärkeanzeige, die auf Entropie statt auf Regeln basiert.

Unser Passwort-Stärke-Test zeigt, wie sich diese Kriterien von den alten Regeln unterscheiden: Er schätzt die Knackzeit anhand von Entropie und Mustererkennung und gleicht das Passwort mit Leak-Daten ab – ein weit nützlicheres Feedback als ein rotes „Sonderzeichen fehlt“.

MFA und Passkeys

Multi-Faktor-Authentifizierung macht ein gestohlenes Passwort zur Sackgasse. Bieten Sie sie allen an und verlangen Sie sie für Admin-, Finanz- und Support-Rollen. Ordnen Sie die Optionen nach Phishing-Resistenz: Passkeys und FIDO2-Sicherheitsschlüssel lassen sich nicht phishen, weil der Schlüssel an Ihren echten Origin gebunden ist; Authenticator-Apps (TOTP) sind gut; SMS-Codes sind besser als nichts, können aber per SIM-Swapping abgefangen werden. Passkeys werden von allen aktuellen Browsern und Betriebssystemen unterstützt und ersetzen das Passwort vollständig – womit auch Credential Stuffing als Angriffskategorie wegfällt.

Schützen Sie den Wiederherstellungsweg so sorgfältig wie den Login: Wiederherstellungscodes nur gehasht speichern, E-Mail-Resets mit Einmal-Tokens, die innerhalb von 15 Minuten ablaufen, und keine Sicherheitsfragen.

Rate Limiting, Sperren und Bot-Abwehr

Begrenzen Sie Login-, Registrierungs-, Passwort-Reset- und MFA-Endpunkte pro IP und pro Konto, und antworten Sie nach Erreichen des Limits mit 429 Too Many Requests und einem Retry-After-Header (unser Leitfaden zu HTTP-Fehler 429 erklärt, wie Clients reagieren sollten). Kombinieren Sie das mit einer wachsenden Verzögerung oder einer temporären Sperre nach wiederholten Fehlversuchen bei einem Konto sowie mit einem CAPTCHA oder einer Proof-of-Work-Challenge für Endpunkte, die verteilte Angriffe abbekommen. Protokollieren Sie jeden fehlgeschlagenen Login mit Quell-IP, damit das Muster eines Credential-Stuffing-Laufs in Minuten statt in Monaten sichtbar wird.

nginx
# nginx: 5 login attempts per minute per client IP
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location = /api/login {
    limit_req zone=login burst=4 nodelay;
    limit_req_status 429;
    proxy_pass http://app;
}

Warnung

Halten Sie die Fehlermeldungen für „unbekannter Benutzer“ und „falsches Passwort“ identisch, und sorgen Sie für die gleiche Antwortzeit (hashen Sie ein Dummy-Passwort, wenn der Benutzer nicht existiert). Sonst dient das Login-Formular nebenbei als API zur Benutzer-Enumeration.

Sessions, Cookies und CSRF

Nach dem Login ist das Session-Cookie der Benutzer – es verdient also denselben Schutz wie das Passwort. Drei Cookie-Attribute und ein Namenspräfix erledigen den Großteil der Arbeit:

  • Secure sorgt dafür, dass das Cookie nie über unverschlüsseltes HTTP gesendet wird und sich so nicht im öffentlichen WLAN mitschneiden lässt.

  • HttpOnly macht es für JavaScript unsichtbar, sodass eine XSS-Lücke es nicht auslesen kann.

  • SameSite=Lax (oder Strict für Admin-Panels) hält es aus Cross-Site-POST-Anfragen heraus und neutralisiert damit die meisten CSRF-Angriffe.

  • Das Präfix __Host- lässt den Browser das Cookie nur akzeptieren, wenn es Secure ist, Path=/ und kein Domain-Attribut hat – so kann eine Subdomain es nicht überschreiben.

http
Set-Cookie: __Host-session=9f1c7e2a...; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=28800

Tipp

Zustandsändernde Aktionen dürfen niemals per GET erreichbar sein. Ein Link wie /account/delete?id=42 lässt sich über ein <img>-Tag auf jeder beliebigen Seite auslösen, die der Nutzer besucht – ganz gleich, wie gut Ihre Cookie-Flags sind.

CSRF: Eine zweite Verteidigungslinie hinter SameSite

Cross-Site Request Forgery (CSRF) bringt einen eingeloggten Browser dazu, von einer anderen Seite aus eine zustandsändernde Anfrage an Ihre Website zu senden. SameSite-Cookies stoppen den Normalfall, doch behalten Sie für jede Nicht-GET-Anfrage eine zweite Abwehr bei: ein Anti-CSRF-Token pro Session in einem versteckten Feld oder einem eigenen Header, oder eine Prüfung, ob der Header Origin (oder Sec-Fetch-Site) zu Ihrem eigenen Origin passt. Die meisten Frameworks (Django, Rails, Laravel, Next.js Server Actions) tun das standardmäßig; der Fehler besteht darin, es für einen API-Endpunkt abzuschalten und diesen Endpunkt dann doch aus dem Browser aufzurufen.

Session-IDs, Rotation und JWTs

Erzeugen Sie Session-IDs mit mindestens 128 Bit Zufall, rotieren Sie die ID beim Login und bei jeder Rechteänderung, um Session Fixation zu verhindern, lassen Sie Sessions nach Inaktivität ablaufen und geben Sie Nutzern einen „Überall abmelden“-Button, der die Sessions serverseitig ungültig macht. Für JWTs gilt: kurzlebig halten (Minuten, mit einem widerrufbaren Refresh-Token), niemals in localStorage speichern, wo jedes Skript sie lesen kann, und einen geleakten Signaturschlüssel als vollständigen Einbruch behandeln, denn jedes jemals damit signierte Token lässt sich nun fälschen.

Eingaben validieren, Ausgaben kodieren

Injection (A05:2025) und Cross-Site-Scripting sind derselbe Fehler an verschiedenen Stellen: Daten eines Nutzers werden an einen Interpreter (SQL, die Shell, eine LDAP-Abfrage, eine HTML-Seite) übergeben, als wären sie Code. Die Lösung ist ebenfalls überall dieselbe: Daten und Code strikt trennen und niemals einen Befehl per String-Verkettung zusammenbauen.

Advertisement

Parametrisierte Abfragen statt zusammengebauter Strings

Verwenden Sie für SQL Prepared Statements oder ein ORM, das sie erzeugt; die Datenbank behandelt die Eingabe dann als Wert, der die Struktur der Abfrage nie verändern kann. Dieselbe Regel gilt für Shell-Befehle (ein Argument-Array übergeben, nie einen String), für NoSQL-Filter (Operator-Objekte wie {"$gt": ""} in Nutzereingaben ablehnen) und für Dateipfade (den Pfad auflösen und prüfen, dass er im vorgesehenen Verzeichnis bleibt).

javascript
// Vulnerable: the input becomes part of the query text
const rows = await db.query(`SELECT * FROM users WHERE email = '${email}'`);

// Safe: the driver sends the value separately from the query
const rows = await db.query("SELECT * FROM users WHERE email = $1", [email]);

// Python / psycopg: same idea
cur.execute("SELECT * FROM users WHERE email = %s", (email,))

Output-Encoding stoppt XSS

Cross-Site-Scripting entsteht, wenn nutzergesteuerter Text in eine Seite geschrieben wird, ohne ihn für den jeweiligen Kontext zu kodieren. Moderne Template-Engines (React und JSX, Vue, Jinja2, Blade, ERB) kodieren standardmäßig; XSS entsteht heute meist über die Notausgänge: dangerouslySetInnerHTML, v-html, |safe, innerHTML sowie URLs oder Inline-Event-Handler, die aus Nutzerdaten gebaut werden. Kodieren Sie exakt für den jeweiligen Kontext, und bereinigen Sie Rich-HTML mit einer spezialisierten Bibliothek wie DOMPurify statt mit einer Regex.

Wo die Daten landenKodieren alsBeispiel
HTML-BodyHTML-Entities< wird zu &lt;, " wird zu &quot;
HTML-AttributEntities in einem Attribut mit AnführungszeichenAttributwert immer in Anführungszeichen setzen; " und ' kodieren
JavaScriptNicht in Skripttext einfügen; Daten über data--Attribute oder einen JSON-Block <script type="application/json"> übergeben</script> in einem String wird zu \u003c/script\u003e
URL-ParameterProzentkodierungencodeURIComponent(value)
CSS-WertGanz vermeiden; Klassennamen aus einer Allowlist wählenNutzereingaben nie in style interpolieren

SSRF, Datei-Uploads und Deserialisierung

Server-Side Request Forgery (SSRF): Ruft Ihr Server eine von Nutzern angegebene URL ab (Webhooks, Bild-Proxys, Link-Vorschauen), kann ein Angreifer ihn auf interne Dienste oder den Cloud-Metadaten-Endpunkt 169.254.169.254 richten und Zugangsdaten auslesen. Lösen Sie zuerst den Hostnamen auf, lehnen Sie private und Link-Local-Bereiche ab, deaktivieren Sie Weiterleitungen und betreiben Sie Fetcher in einem Netzwerksegment, das nichts Internes erreichen kann.

Datei-Uploads: Prüfen Sie den Typ anhand des Inhalts, nicht anhand der Dateiendung oder des vom Client gesendeten Content-Type; erzwingen Sie eine Größenbegrenzung; speichern Sie Dateien außerhalb des Web-Roots oder in einem Object Storage unter einem von Ihnen erzeugten Zufallsnamen; und liefern Sie sie nach Möglichkeit von einem separaten Origin mit nosniff und Content-Disposition: attachment aus. Ein Upload darf nie an einem Ort landen, an dem der Webserver ihn ausführt.

Deserialisierung und Mass Assignment: Deserialisieren Sie niemals nicht vertrauenswürdige Daten mit einem Format, das beliebige Klassen instanziieren kann (native Java-Serialisierung, Python pickle, PHP unserialize, YAML mit Custom Tags); verwenden Sie JSON mit einem Schema. Binden Sie Request-Bodys an eine explizite Allowlist von Feldern, damit ein Nutzer nicht "role": "admin" in ein Modell posten kann, das zufällig diese Spalte hat.

Warnung

Validierung prüft die Form (Ist das eine E-Mail-Adresse, eine positive Ganzzahl, einer dieser fünf Werte?), nicht die Sicherheit. Blocklisten, die <script> oder Anführungszeichen herausfiltern, lassen sich immer umgehen. Akzeptieren Sie nur, was Sie erwarten, kodieren Sie dann bei der Ausgabe und parametrisieren Sie beim Speichern.

Broken Access Control: Das Risiko Nummer eins

Broken Access Control steht seit 2021 an der Spitze der OWASP Top 10 und behält diesen Platz als A01:2025. Es ist kein einzelner Bug, sondern eine Gewohnheit: zu prüfen, wer jemand ist (Authentifizierung), und dabei zu vergessen, bei jeder Anfrage zu prüfen, worauf er zugreifen darf (Autorisierung). Die klassische Form ist die Insecure Direct Object Reference: GET /api/invoices/1042 funktioniert für den Eigentümer der Rechnung – und für jeden, der die Nummer ändert.

  • Standardmäßig verweigern. Jede Route braucht eine explizite Regel, die Zugriff gewährt; eine fehlende Regel bedeutet 403, nicht 200.

  • Serverseitig und pro Objekt prüfen. Einen Button in der Oberfläche auszublenden ist keine Zugriffskontrolle. Jeder Lese- und Schreibzugriff muss bestätigen, dass der aktuelle Nutzer den konkreten Datensatz besitzt oder darauf zugreifen darf – auch in Bulk-Endpunkten, Exporten und Hintergrund-Jobs.

  • Nicht erratbare IDs verwenden, wo es hilft (UUIDs), sich aber nie darauf verlassen: Verschleierung ist keine Autorisierung.

  • CORS abriegeln. Access-Control-Allow-Origin: * mit Credentials oder das Zurückspiegeln jedes beliebigen Origin aus der Anfrage liefert Ihre API jeder Website aus, die der Nutzer besucht.

  • Verzeichnislisten deaktivieren, .git, .env, Backup- und Konfigurationsdateien auf Webserver-Ebene blockieren und Admin-Panels aus dem öffentlichen Internet heraushalten oder hinter MFA und IP-Allowlists stellen.

  • Autorisierungsfehler begrenzen und protokollieren. Eine Häufung von 403-Antworten aus einer Session ist ein laufender Enumerationsangriff.

javascript
// Express: ownership check on every object access
app.get("/api/invoices/:id", requireAuth, async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  if (!invoice || invoice.ownerId !== req.user.id) {
    return res.status(404).end(); // 404, not 403: don't confirm the record exists
  }
  res.json(invoice);
});

Hinweis

Testen Sie die Zugriffskontrolle so, wie ein Angreifer es tut: Melden Sie sich als Nutzer mit geringen Rechten an, zeichnen Sie jede Anfrage auf und spielen Sie jede davon mit den IDs eines anderen Nutzers und ohne Authorization-Header erneut ab. Automatisierte Scanner finden Injection; Autorisierungsfehler finden sie fast nie – deshalb überleben diese Bugs jahrelang.

Schicht 5: Abhängigkeiten und Software-Lieferkette

Eine typische Webanwendung besteht vielleicht zu 5 % aus selbst geschriebenem und zu 95 % aus heruntergeladenem Code. Deshalb steigt Software Supply Chain Failures in den OWASP Top 10 von 2025 direkt auf A03 ein, und deshalb hat die Ausnutzung von Schwachstellen im DBIR 2026 gestohlene Zugangsdaten überholt. Im September 2025 schleuste ein einziger per Phishing kompromittierter Maintainer Malware zum Stehlen von Kryptowährungen in chalk, debug und 16 weitere npm-Pakete ein, die zusammen über zwei Milliarden Downloads pro Woche verzeichnen; jedes Projekt, das in diesem Zeitfenster eine nicht gepinnte Version installierte, zog sie automatisch mit.

  • Committen Sie ein Lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, poetry.lock, go.sum) und installieren Sie in der CI mit npm ci, damit Builds reproduzierbar sind und kein neues Upstream-Release ungeprüft hineinrutscht.

  • Scannen Sie kontinuierlich: npm audit, pip-audit, bundler-audit, GitHub Dependabot oder Renovate für Updates und einen Container-Scanner wie Trivy oder Grype für die Betriebssystemebene.

  • Verzögern Sie Upgrades ohne Sicherheitsbezug um einige Tage (minimumReleaseAge in Renovate), damit ein vergiftetes Release meist schon zurückgezogen ist, bevor Sie es übernehmen – Sicherheitspatches spielen Sie dagegen sofort ein.

  • Pinnen Sie Actions und Skripte von Drittanbietern in der CI auf einen Commit-SHA, und verwenden Sie Subresource Integrity (integrity="sha384-...") für jedes Skript, das Sie von einem öffentlichen CDN laden.

  • Geben Sie der CI minimale Rechte: wo möglich schreibgeschützte Tokens, kurzlebige OIDC-Credentials statt langlebiger Secrets und Veröffentlichungsrechte nur für einen Release-Job.

  • Erzeugen Sie beim Build eine SBOM (CycloneDX oder SPDX), damit Sie die Frage „Sind wir betroffen?“ in Minuten beantworten können, wenn die nächste CVE vom Kaliber Log4Shell auftaucht.

bash
# Reproducible install + audit in CI
npm ci --ignore-scripts
npm audit --audit-level=high

# Pin a GitHub Action to a commit, not a floating tag
# uses: actions/checkout@v4                 <- can change underneath you
# uses: actions/checkout@<full-commit-sha>  # v4.2.2

# Subresource Integrity for a CDN script (hash from: openssl dgst -sha384 -binary lib.min.js | openssl base64 -A)
<script src="https://cdn.example.com/lib.min.js"
        integrity="sha384-<base64-hash>"
        crossorigin="anonymous"></script>

Tipp

npm ci --ignore-scripts blockiert die Install-Skripte, über die sich die meiste npm-Malware ausführt; aktivieren Sie Skripte danach gezielt nur für die wenigen Pakete, die wirklich einen Build-Schritt brauchen.

Wenn Sie WordPress oder ein anderes CMS betreiben, gelten dieselben Regeln für Plugins und Themes – dort beginnen die meisten CMS-Kompromittierungen. Halten Sie den Core und jedes Plugin aktuell, löschen Sie alles Ungenutzte, und prüfen Sie mit dem CMS-Detector, was ein Scanner über Ihre Versionen herausfinden kann.

Schicht 6: Server-Härtung: Ports, Patches, Secrets und Backups

Die Anwendungsschicht ist bedeutungslos, wenn der Server darunter Passwort-Logins per SSH akzeptiert, eine Datenbank auf einem öffentlichen Port betreibt oder seit seiner Einrichtung nie gepatcht wurde. Best Practices für Server sind langweilig – und genau hier dringt Ransomware ein.

Schließen Sie jeden Port, den Sie nicht bedienen

Ein öffentlicher Webserver braucht offene Ports 80 und 443 sowie SSH aus Ihrem eigenen IP-Bereich. Datenbanken (3306, 5432, 27017), Redis (6379), Elasticsearch (9200), Admin-Panels und Metrik-Endpunkte sollten nur an localhost oder ein privates Netzwerk gebunden sein. Prüfen Sie nach jeder Änderung von außen mit dem Port-Checker – das ist die Sicht, die ein Angreifer hat, und Cloud-Security-Groups sind leicht falsch zu lesen.

bash
# Ubuntu: default-deny firewall, allow only web + SSH from your office range
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo ufw enable

# SSH: keys only, no root password login
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
sudo systemctl reload ssh

Nach Plan patchen, Secrets aus dem Code halten

Aktivieren Sie unbeaufsichtigte Sicherheitsupdates für das Betriebssystem, abonnieren Sie die Security-Mailinglisten Ihrer Runtime und Ihres Frameworks, und behandeln Sie eine kritische CVE in allem, was aus dem Internet erreichbar ist, als Aufgabe für denselben Tag. Betreiben Sie Dienste als unprivilegierte Benutzer, in Containern oder mit systemd-Sandboxing, damit ein kompromittierter Prozess nicht die ganze Maschine auslesen kann.

Secrets (Datenbankpasswörter, API-Schlüssel, Signaturschlüssel) gehören niemals ins Repository, in eine Docker-Image-Schicht oder in clientseitiges JavaScript. Laden Sie sie aus Umgebungsvariablen, die beim Deployment injiziert werden, oder aus einem Secrets-Manager, rotieren Sie sie, wenn jemand mit Zugriff das Team verlässt, und durchsuchen Sie die Repository-Historie mit einem Tool wie gitleaks – denn ein einmal committeter Schlüssel ist für immer kompromittiert, auch wenn der Commit später entfernt wird.

Warnung

Alles mit dem Präfix NEXT_PUBLIC_, VITE_ oder REACT_APP_ wird in das Browser-Bundle gepackt und ist per Definition öffentlich. Legen Sie API-Schlüssel von Drittanbietern stattdessen hinter eine eigene Server-Route. Unser Leitfaden zum Testen eines öffentlichen API-Endpunkts zeigt, wie Sie prüfen, was Ihr Frontend tatsächlich preisgibt.

Ransomware-feste Backups und ein CDN davor

Befolgen Sie die 3-2-1-Regel: drei Kopien auf zwei verschiedenen Medien, eine davon außer Haus – und machen Sie mindestens eine Kopie unveränderlich oder offline, damit Ransomware, die den Server erreicht, nicht auch die Backups verschlüsseln kann. Verschlüsseln Sie Backups, schließen Sie die Datenbank und das Upload-Verzeichnis ein, und – ganz entscheidend – testen Sie regelmäßig eine Wiederherstellung. Ein Backup, aus dem nie jemand etwas wiederhergestellt hat, ist eine Hoffnung, kein Plan. Die Wiederherstellungszeit entscheidet, ob ein Vorfall ein bloßer Ausfall bleibt oder das Ende des Unternehmens bedeutet.

Stellen Sie ein CDN oder eine WAF (Cloudflare, Fastly, AWS CloudFront mit WAF oder das Pendant Ihres Hosters) vor den Origin-Server. Es fängt volumetrische DDoS-Angriffe ab, wendet verwaltete Regeln gegen gängige Injection-Payloads und bösartige Bots an, verbirgt Ihre Origin-IP und bietet Ihnen einen Ort, um Rate Limits und Geo-Regeln durchzusetzen, ohne die Anwendung anzufassen. Beschränken Sie dann die Firewall des Origins so, dass nur die IP-Bereiche des CDN Port 443 direkt erreichen; andernfalls gehen Angreifer einfach außen herum. Der Hosting-Checker zeigt, ob der echte Origin einer Website hinter ihrem CDN offenliegt.

E-Mail-Authentifizierung: SPF, DKIM und DMARC

Zur Websicherheit gehört auch die E-Mail, über die Ihre Passwort-Resets, Rechnungen und Support-Antworten laufen. Ohne SPF, DKIM und DMARC kann jeder E-Mails als billing@yourdomain.com versenden, und seit Februar 2024 verlangen Google und Yahoo alle drei von Massenversendern. Der komplette Satz besteht aus drei DNS-TXT-Einträgen:

dns
yourdomain.com.                    TXT  "v=spf1 include:_spf.google.com -all"
google._domainkey.yourdomain.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
_dmarc.yourdomain.com.             TXT  "v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s"

Hinweis

DMARC p=reject ist zugleich eine Maßnahme zum Markenschutz: Nur so verhindern Sie, dass eine Phishing-Kampagne exakt Ihre Domain in die Absenderzeile setzt. Die aggregierten Berichte (rua=) zeigen Ihnen, wer es versucht.

Starten Sie DMARC mit p=none, um Berichte zu sammeln, und wechseln Sie zu p=quarantine und dann zu p=reject, sobald jeder legitime Absender (Marketing-Plattform, Helpdesk, CRM) das Alignment besteht. Ergänzen Sie MTA-STS- und TLS-RPT-Einträge, um verschlüsselte Zustellung an Ihre Mailserver zu erzwingen, und veröffentlichen Sie auf Domains, die nie E-Mails versenden, einen Null-MX (MX 0 .), damit sie sich gar nicht erst fälschen lassen. Prüfen Sie jeden Eintrag mit dem SPF-Checker, DKIM-Checker und DMARC-Checker, und gleichen Sie Ihre Versand-IPs mit dem IP-Blacklist-Checker gegen Blocklisten ab, wenn die Zustellbarkeit sinkt.

Protokollieren, überwachen und für den Ernstfall planen

Zwei der zehn OWASP-Kategorien von 2025 drehen sich darum, was nach einem Fehler passiert: Security Logging and Alerting Failures (A09) und die neue Kategorie Mishandling of Exceptional Conditions (A10). Der typische Einbruch bleibt noch immer monatelang unentdeckt, weil die Spuren nie aufgezeichnet wurden – oder aufgezeichnet wurden und niemand hingesehen hat.

  • Protokollieren Sie Sicherheitsereignisse mit Kontext: jeden erfolgreichen und fehlgeschlagenen Login, MFA-Änderungen, Passwort-Resets, Rechteänderungen, verweigerte Zugriffe, fehlgeschlagene Eingabevalidierungen und Admin-Aktionen, jeweils mit Zeitstempel, Benutzer-ID, Quell-IP und User-Agent.

  • Protokollieren Sie niemals Secrets: Passwörter, Session-Tokens, vollständige Kartennummern, API-Schlüssel. Maskieren Sie sie in der Logging-Schicht, nicht an jeder einzelnen Aufrufstelle.

  • Leiten Sie Logs vom Server weg in einen zentralen Speicher (CloudWatch, Loki, Elastic, ein SIEM) mit mindestens 90 Tagen Aufbewahrung, damit ein Angreifer mit Root-Rechten seine Spuren nicht verwischen kann.

  • Alarmieren Sie bei Mustern, nicht bei Einzelereignissen: 50 fehlgeschlagene Logins in einer Minute, eine Häufung von 403-Antworten aus einer Session, ein außerhalb der Geschäftszeiten angelegter neuer Admin, ein Zertifikat für Ihre Domain, das Sie nicht beantragt haben.

  • Im Zweifel blockieren (Fail Closed): Wenn eine nachgelagerte Prüfung (Auth-Dienst, Rate Limiter, WAF) einen Fehler liefert, lehnen Sie die Anfrage ab. A10 gibt es, weil so viele Systeme Zugriff gewähren, wenn die Prüfung, die ihn hätte blockieren sollen, eine Exception wirft.

  • Überwachen Sie von außen: Verfügbarkeit, Zertifikatsablauf, DNS-Änderungen, Blocklisteneinträge und Header-Regressionen. Der Domain-Health-Check bündelt DNS-, SSL-, E-Mail-Authentifizierungs- und Header-Tests in einer Bewertung, die Sie nach jedem Deployment erneut ausführen können.

Schreiben Sie den Incident-Response-Plan, bevor Sie ihn brauchen

Legen Sie vorab fest, wer Rufbereitschaft hat, wie jedes Credential rotiert wird, wie Sie die Website in einen Nur-Lese-Modus versetzen, wo die sauberen Backups liegen und welche Aufsichtsbehörde oder welche Kunden innerhalb wie vieler Stunden zu benachrichtigen sind (72 nach der DSGVO). Führen Sie einmal im Jahr eine Tabletop-Übung durch. Teams mit einem geprobten Plan erholen sich in Tagen; Teams ohne Plan improvisieren wochenlang.

Tipp

Legen Sie eine security.txt-Datei unter /.well-known/security.txt an (RFC 9116), mit Kontaktadresse und PGP-Schlüssel. Sicherheitsforscher, die einen Bug in Ihrer Website finden, nutzen sie – die Alternative ist, dass sie ihn öffentlich posten.

Testen: Scanner, Penetrationstests und laufende Prüfungen

Jede Maßnahme oben lässt sich überprüfen, und die Prüfung sollte wo immer möglich automatisiert sein, damit sie nicht verkümmert. Eine sinnvolle Stufenleiter, von kostenlos und sofort bis periodisch und kostenpflichtig:

PrüfungToolWie oft
TLS-Konfiguration, Kette, AblaufSSL-Checker, SSL Labs, testssl.shNach jeder Zertifikats- oder Serveränderung; Ablauf täglich
Sicherheitsheader und CSPHTTP-Header-Checker, MDN HTTP ObservatoryNach jedem Deployment (in die CI aufnehmen)
Offene PortsPort-Checker, nmapNach jeder Firewall- oder Cloud-Änderung
DNS, DNSSEC, E-Mail-AuthentifizierungDomain-Health-Check, DMARC-CheckerMonatlich und nach jeder DNS-Änderung
Veraltete SubdomainsSubdomain-FinderVierteljährlich und bei jeder Stilllegung
Abhängigkeiten mit bekannten Schwachstellennpm audit, Dependabot, TrivyBei jedem Build
Schwachstellen im Code (SAST)Semgrep, CodeQLBei jedem Pull Request
Web-Schwachstellen zur Laufzeit (DAST)OWASP ZAP, NucleiWöchentlich gegen Staging
Autorisierung und GeschäftslogikManueller Penetrationstest oder Bug-Bounty-ProgrammJährlich und nach größeren Features

Scanner sind gut bei Injection, Headern und veralteten Komponenten und schlecht bei Autorisierung und Geschäftslogik – planen Sie daher für alles, was mit Geld oder personenbezogenen Daten umgeht, mindestens einen manuellen Test pro Jahr ein. Beheben Sie Funde nach Angriffsfläche: Was ein nicht angemeldeter Nutzer aus dem Internet ausnutzen kann, kommt zuerst.

Die Checkliste für Website-Sicherheit

Kopieren Sie sie in die README Ihres Projekts oder in Ihren Ticket-Tracker. Jede Zeile entspricht einer der Maßnahmen oben und ist so formuliert, dass sie sich als erledigt oder nicht erledigt abhaken lässt; die letzte Spalte ist der Nachweis.

SchichtMaßnahmeErledigt, wenn
DomainRegistrar Lock und MFA für das Registrar-Konto; automatische Verlängerung aktivWHOIS zeigt clientTransferProhibited; Ablauf mehr als 12 Monate entfernt
DNSDNSSEC-signiert; CAA-Eintrag nennt nur Ihre CAsdig +dnssec liefert RRSIG; DS-Eintrag in der übergeordneten Zone vorhanden
DNSKeine verwaisten CNAME- oder A-EinträgeJeder Hostname aus dem Subdomain-Finder zeigt auf etwas, das Sie kontrollieren
TLSNur TLS 1.2+, TLS 1.3 bevorzugt, vollständige Kette ausgeliefertSSL-Checker: Kette vollständig, TLS 1.0/1.1 abgelehnt
TLSHSTS mit einem Jahr max-age, includeSubDomains, im PreloadAuf hstspreload.org gelistet
TLSErneuerung per ACME automatisiert; Ablauf überwachtcertbot renew --dry-run läuft durch; Alarm bei 14 Tagen eingerichtet
HeaderCSP (Nonce-basiert), frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicyHTTP-Header-Checker: Note A
AuthHashing mit Argon2id oder bcrypt; NIST-Passwortregeln; Abgleich mit Leak-ListenEin Hash dauert 100 bis 250 ms; keine Kompositionsregeln
AuthMFA für alle angeboten, für Admins Pflicht; Passkeys unterstütztAdmin-Login ohne zweiten Faktor unmöglich
AuthLogin-, Reset- und MFA-Endpunkte pro IP und pro Konto begrenztSechster Versuch innerhalb einer Minute liefert 429
Sessions__Host--Cookie mit Secure, HttpOnly, SameSite; ID beim Login rotiertCookie-Attribute in den DevTools sichtbar; alte Session nach Login ungültig
EingabenÜberall parametrisierte Abfragen; Ausgabe kontextgerecht kodiert; Uploads anhand des Inhalts validiertCodesuche findet keine zusammengebauten Query-Strings; XSS-Payloads erscheinen als Text
ZugriffskontrolleRouting nach Deny-by-Default; Eigentümerprüfung pro Objekt; strikte CORS-RegelnAbspielen fremder IDs liefert 404 oder 403
AbhängigkeitenLockfile committet; npm ci; Audit in der CI; Actions auf SHA gepinnt; SRI für CDN-SkripteBuild schlägt bei einer CVE mit hohem Schweregrad fehl
ServerNur 80 und 443 öffentlich; SSH nur mit Schlüssel; unbeaufsichtigte Sicherheitsupdates; Secrets in Env oder VaultPort-Checker zeigt 22, 3306 und 6379 aus dem Internet geschlossen
Backups3-2-1 mit einer unveränderlichen Kopie; Wiederherstellung getestetLetzter erfolgreicher Wiederherstellungstest liegt höchstens 90 Tage zurück
E-MailSPF -all, DKIM, DMARC p=reject, MTA-STSDMARC-Checker besteht; aggregierte Berichte gehen ein
MonitoringAuthentifizierungs- und Autorisierungsereignisse zentral protokolliert; Alarme bei Mustern; externes Monitoring von Verfügbarkeit, Zertifikaten und DNSTestalarm ausgelöst und empfangen
ReaktionSchriftlicher Incident-Plan; security.txt veröffentlicht; Tabletop-Übung durchgeführtPlan in den letzten 12 Monaten überprüft

So passt das zu den OWASP Top 10:2025

Die OWASP Top 10 sind die meistzitierte Liste von Risiken für Webanwendungen; die Ausgabe 2025 hat die Reihenfolge neu gemischt und zwei neue Kategorien eingeführt. Wenn ein Kunde, Auditor oder Compliance-Framework fragt, wie Sie damit umgehen, ist dies die Zuordnung zu den Maßnahmen in diesem Leitfaden:

OWASP Top 10:2025Maßnahmen in diesem Leitfaden
A01 Broken Access ControlDeny by Default, Prüfungen pro Objekt, strikte CORS-Regeln, abgeschottete Admin-Bereiche
A02 Security MisconfigurationSicherheitsheader, HSTS, geschlossene Ports, entfernte Versions-Header, Verzeichnislisten deaktiviert
A03 Software Supply Chain Failures (neu)Lockfiles, Audits, gepinnte Actions, SRI, SBOM, CI mit minimalen Rechten
A04 Cryptographic FailuresTLS 1.2+ und 1.3, HSTS, Argon2id, Secrets-Management, verschlüsselte Backups
A05 InjectionParametrisierte Abfragen, Output-Encoding, CSP, Upload-Validierung
A06 Insecure DesignBedrohungsmodell pro Schicht, Fail-Closed-Voreinstellungen, Rate Limiting als Designprinzip
A07 Authentication FailuresNIST-Passwortregeln, Leak-Prüfungen, MFA und Passkeys, Session-Rotation
A08 Software or Data Integrity FailuresSRI, signierte und gepinnte Abhängigkeiten, sichere Deserialisierung
A09 Security Logging and Alerting FailuresZentrales Logging, Alarme bei Mustern, externes Monitoring
A10 Mishandling of Exceptional Conditions (neu)Fail Closed, einheitliche Fehlerantworten, keine Stacktraces an Nutzer

Hinweis

Der ASVS von OWASP (Application Security Verification Standard) macht aus demselben Material eine nummerierte Checkliste für Audits. Level 1 ist ein realistisches Ziel für jede öffentliche Website, Level 2 für alles, was personenbezogene oder finanzielle Daten verarbeitet.

Prüfen Sie die Sicherheitsheader Ihrer Website in Sekunden

Der kostenlose HTTP-Header-Checker von DNS Robot ruft jede URL ab und bewertet ihre Sicherheitsheader von A bis F: HSTS, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy und Permissions-Policy – mit dem exakt gefundenen Wert und allem, was fehlt. Ohne Anmeldung.

Testen HTTP-Header-Checker

Advertisement

Häufige Fragen zur Website-Sicherheit

Erzwingen Sie HTTPS mit modernem TLS und HSTS, senden Sie strikte Sicherheitsheader (vor allem eine Content Security Policy), hashen Sie Passwörter mit Argon2id und sichern Sie Logins mit MFA und Rate Limiting ab, verwenden Sie parametrisierte Abfragen und Output-Encoding, setzen Sie die Zugriffskontrolle serverseitig für jedes Objekt durch, halten Sie Abhängigkeiten gepatcht und gepinnt, schließen Sie ungenutzte Ports und protokollieren Sie Sicherheitsereignisse zentral. Sichern Sie zuerst Domain und DNS ab, denn alles andere setzt voraus, dass Sie Ihren Namen noch kontrollieren.

Verwandte Tools

HTTP Headers CheckSSL Certificate CheckPort CheckerDomain Health CheckerDMARC CheckerSubdomain FinderPassword Strength Tester

Verwandte Artikel

Was ist eine SSL-Zertifikatskette? So funktioniert sieX-Frame-Options Explained: Fix “Refused to Connect” in an iframeHTTP Error 429 Too Many Requests: Ursachen & LösungenWHOIS-Abfrage: Domaininhaber finden und den Eintrag lesen

Inhaltsverzeichnis

  • Website-Sicherheit: Was Best Practices wirklich bedeuten
  • Der Web-Security-Stack: Sechs Schichten, die Sie schützen müssen
  • Schicht 1: Domain und DNS absichern
  • Schicht 2: HTTPS und TLS richtig umsetzen
  • Schicht 3: HTTP-Sicherheitsheader
  • Schicht 4: Authentifizierung, die Credential Stuffing standhält
  • Sessions, Cookies und CSRF
  • Eingaben validieren, Ausgaben kodieren
  • Broken Access Control: Das Risiko Nummer eins
  • Schicht 5: Abhängigkeiten und Software-Lieferkette
  • Schicht 6: Server-Härtung: Ports, Patches, Secrets und Backups
  • E-Mail-Authentifizierung: SPF, DKIM und DMARC
  • Protokollieren, überwachen und für den Ernstfall planen
  • Testen: Scanner, Penetrationstests und laufende Prüfungen
  • Die Checkliste für Website-Sicherheit
  • So passt das zu den OWASP Top 10:2025
  • Häufig gestellte Fragen