Der erste Angriff auf deine Website ist kein Angriff. Es ist eine Handvoll harmloser Anfragen: ein GET /, ein Blick auf die Antwort-Header und den Quelltext, eine TLS-Verbindung, ein paar DNS-Abfragen. Niemand bricht ein, niemand probiert Passwörter. Trotzdem weiß die Gegenseite danach mehr über deinen Server, als die meisten Betreiber selbst wissen.
Das ist Arbeitsteilung. Wer Websites in großem Stil angreift, scannt vorher in großem Stil. Suchmaschinen für Server wie Shodan oder Censys, Massen-Scanner wie Nuclei, selbstgeschriebene Skripte: Sie alle lesen zuerst nur, was ein Server freiwillig ausliefert, und sortieren danach. Am dankbarsten ist eine Versionsnummer im Quelltext. jquery-1.12.4.min.js ist für einen Scanner kein Dateiname, sondern ein Nachschlagebefehl: Version rein, Liste bekannter Lücken raus. Eine Domain mit so einer Zeile, einem abgelaufenen Zertifikat und einer öffentlich erreichbaren .env-Datei landet auf der kurzen Liste. Eine Domain, bei der die Grundkonfiguration stimmt, ist für diesen Schritt uninteressant, weil der nächste Kandidat leichter ist.
Diese Vorsortierung kannst du selbst nachspielen. Unser kostenloser Security Check liest deine Startseite, dein Zertifikat und dein öffentliches DNS so, wie es ein Scanner tut. Keine Exploits, kein Login, nur Lesezugriffe; in deinen Server-Logs erkennst du ihn am User-Agent nextlevels-Security-Check/1.0. Seine sechs Kategorien sind dieselben sechs Dinge, die ein Angreifer zuerst prüft.
Check 1: HTTPS & TLS. Sehen deine Besucher eine Browser-Warnung?
Verschlüsselung ist längst die Grundannahme. Der Browser bestraft jede Abweichung sofort und sichtbar: Die Seite wird als „Nicht sicher“ markiert, bei einem ungültigen Zertifikat erscheint eine Warnseite, an der viele Besucher abspringen. Für einen Shop ist das kein Sicherheits-, sondern ein Umsatzproblem.
Von außen interessieren vor allem die Lücken in der Verschlüsselung. Antwortet der Server auch auf Port 80 mit Inhalt statt mit einer Weiterleitung, lässt sich die erste Verbindung in einem offenen WLAN auf eine Kopie umleiten. Passt das Zertifikat nicht zum Hostnamen oder läuft es in wenigen Tagen ab, verrät das eine Betriebsorganisation, die nicht hinschaut.
Fehlt im DNS ein CAA-Eintrag, darf jede Zertifizierungsstelle der Welt ein Zertifikat für deine Domain ausstellen. Wer eine davon täuscht, bekommt ein gültiges Zertifikat für deinen Namen, und jeder Browser würde es akzeptieren.
Das Ablaufdatum wird gerade zum Dauerthema. Das CA/Browser Forum hat 2025 beschlossen, die maximale Laufzeit öffentlicher TLS-Zertifikate schrittweise zu verkürzen: seit dem 15. März 2026 auf 200 Tage, ab März 2027 auf 100 Tage, ab März 2029 auf 47 Tage (Zeitplan bei DigiCert). Wer Zertifikate heute noch von Hand verlängert, hält das spätestens 2027 nicht mehr durch. Automatische Verlängerung, etwa über ACME, wird damit zur Pflicht.
Die Sollkonfiguration ist unspektakulär: HTTPS auf allen Hostnamen, HTTP leitet mit 301 direkt auf die finale HTTPS-Adresse um, das Zertifikat deckt www und die nackte Domain ab und erneuert sich automatisch. Das BSI empfiehlt in der TR-02102-2 bevorzugt TLS 1.3, TLS 1.2 nur noch bis Ende 2031 und nur mit den dort gelisteten Cipher-Suiten; TLS 1.0 und 1.1 gehören abgeschaltet. Dazu ein CAA-Eintrag mit einer Zeile, etwa deine-domain.de. CAA 0 issue "letsencrypt.org", der festlegt, welche Zertifizierungsstelle überhaupt ausstellen darf.
So sieht das im Check aus
Kein HTTPS ist ein Fehler. Ein ungültiges Zertifikat oder eins, das nicht zum Hostnamen passt, ebenfalls. Leitet HTTP nicht auf HTTPS um, ist das eine Warnung. Der fehlende CAA-Eintrag läuft als Hinweis. Beim Ablaufdatum gibt es zwei Stufen: unter 30 Tagen eine Warnung, unter 7 Tagen ein Fehler.
Check 2: Security-Header. Ist deine Seite gegen eingeschleusten Code und Clickjacking geschützt?
Security-Header sind Anweisungen deines Servers an den Browser: Lade diese Seite nur per HTTPS, führe nur Skripte von diesen Quellen aus, lass dich nicht in fremde Frames einbetten, rate keine Dateitypen. Sie kosten nichts, jeder Browser versteht sie seit Jahren, und sie fehlen trotzdem in vielen Setups. Für einen Scanner ist das der erste Hinweis darauf, dass hier niemand mit Sicherheitsblick über die Konfiguration gegangen ist.
Sechs Header zählen, und sie sind sehr ungleich teuer. Fünf davon setzt du in zehn Minuten, ohne dass sich an deiner Seite etwas ändert. Der sechste, die Content-Security-Policy, ist ein Projekt von ein paar Tagen. Er ist aber auch der einzige, der eine echte Anwendungslücke abfedern kann.
Die schnellen fünf: Strict-Transport-Security (HSTS) sagt dem Browser, die Domain für eine bestimmte Zeit ausschließlich per HTTPS aufzurufen, auch wenn jemand http:// eintippt. Ohne HSTS darf der erste Aufruf unverschlüsselt stattfinden, und dieser erste Aufruf ist der Moment, in dem eine Umleitung im offenen WLAN funktioniert. Die HSTS-Preload-Liste der Browser nimmt Domains nur mit max-age von mindestens einem Jahr, includeSubDomains und preload auf.
X-Content-Type-Options: nosniff verhindert, dass der Browser Dateitypen rät und eine hochgeladene Datei als Skript ausführt. X-Frame-Options oder die CSP-Direktive frame-ancestors verhindern Clickjacking, das unsichtbare Einbetten deiner Seite in eine fremde, auf der ein Besucher scheinbar woanders klickt; MDN verweist für mehr Möglichkeiten auf frame-ancestors.
Referrer-Policy begrenzt, wie viel der aufrufenden URL an Drittseiten geht, strict-origin-when-cross-origin ist der vernünftige Standard. Permissions-Policy schaltet Kamera, Mikrofon oder Geolocation ab, die ein Shop ohnehin nicht braucht.
Die Content-Security-Policy (CSP) legt fest, aus welchen Quellen Skripte, Styles, Bilder und Frames geladen werden dürfen. Eine saubere CSP entschärft Cross-Site-Scripting selbst dann, wenn die Anwendung eine Lücke hat, weil eingeschleuster Code schlicht nicht ausgeführt wird. Der häufigste Fehlgriff ist script-src 'unsafe-inline'. Damit erlaubt die Policy genau das, was XSS braucht, und ist praktisch wirkungslos. Viele Shop- und CMS-Setups setzen das, weil Plugins Inline-Skripte mitbringen. Die Lösung sind Nonces oder Hashes, nicht das Abschalten des Schutzes.
Ein Startpunkt für nginx, der ohne Umbau funktioniert und die CSP bewusst im Report-Only-Modus lässt, damit du siehst, was sie blockieren würde, bevor sie es tut:
# Grundschutz-Header, nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" 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 Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# CSP erst beobachten, dann scharf schalten
add_header Content-Security-Policy-Report-Only "default-src 'self'; frame-ancestors 'self'; report-uri /csp-report" always;
Eine nginx-Eigenheit, die regelmäßig für Verwirrung sorgt: add_header wird nicht vererbt, sobald ein location-Block ein eigenes add_header hat. Dann fehlen in genau diesem Pfad plötzlich alle Header von oben. Trifft es den Block, der die Startseite ausliefert, sieht der Check das sofort; in der Konfigurationsdatei fällt es nicht auf.
Eine Header-Fehlkonfiguration ist teurer als alle fehlenden Header zusammen: CORS, das zu großzügig ist. Antwortet dein Server auf jeden fremden Origin mit genau diesem Origin in Access-Control-Allow-Origin und erlaubt dazu Access-Control-Allow-Credentials: true, darf jede beliebige Website im Browser deiner eingeloggten Kunden Anfragen an dich stellen und die Antworten lesen. Typischer Ursprung ist eine CORS-Fehlermeldung, die schnell verschwinden sollte.
So sieht das im Check aus
Bewertet wird, was deine Startseite nach allen Weiterleitungen tatsächlich ausliefert. Spiegelt der Server einen fremden Origin und erlaubt dazu Credentials, meldet der Check das als Warnung. HSTS besteht ab einer Laufzeit von 180 Tagen. Bei der CSP sucht der Check typische Schwächen wie unsafe-inline, unsafe-eval und den Platzhalter * in default-src oder script-src; eine vollständige CSP-Analyse ist das nicht. X-Powered-By mit Versionsnummer ist eine Warnung; ohne Versionsnummer ist es, wie COOP, CORP, COEP, includeSubDomains und preload, nur ein Hinweis.
Check 3: Cookie-Flags. Können Sitzungs-Cookies abgegriffen werden?
Das Session-Cookie ist der Schlüssel zum eingeloggten Zustand. Wer es hat, ist du, ohne Passwort, ohne Zwei-Faktor-Code. Deshalb sind die drei Attribute, mit denen dieses Cookie gesetzt wird, wichtiger als die Länge deines Passworts.
Secure sorgt dafür, dass der Browser das Cookie ausschließlich über HTTPS mitschickt. Fehlt das Flag, geht es beim ersten unverschlüsselten Aufruf irgendeiner Unterseite im Klartext über die Leitung. HttpOnly nimmt JavaScript den Zugriff auf das Cookie. Gelingt dann doch ein XSS, kann das eingeschleuste Skript die Sitzung wenigstens nicht auslesen und nach Hause schicken, das klassische Ziel eines solchen Angriffs. SameSite steuert, ob das Cookie bei Anfragen mitgesendet wird, die von einer fremden Seite ausgelöst wurden, und ist damit die Verteidigung des Browsers gegen Cross-Site-Request-Forgery.
Chrome und andere Chromium-Browser behandeln seit Chrome 80 im Februar 2020 Cookies ohne SameSite-Angabe standardmäßig als Lax und verlangen für SameSite=None zwingend Secure (Zusammenfassung der Änderung). Laut MDN zum Set-Cookie-Header gilt dieser Standard aber nur in manchen Browsern. „Der Browser macht das schon“ ist also keine Konfiguration. Ein Session-Cookie sollte explizit so gesetzt werden: Set-Cookie: session=…; Path=/; Secure; HttpOnly; SameSite=Lax.
Das Session-Cookie der Anwendung ist oft sauber gesetzt. Die offenen Flanken liegen eher bei Tracking-, Chat- und A/B-Testing-Tools. Viele davon setzen ihre Cookies per JavaScript direkt im Browser. Solche Cookies können per Definition nicht HttpOnly sein und tauchen in keinem Set-Cookie-Header auf, also auch nicht in diesem Check. Welche du überhaupt vor einer Einwilligung setzen darfst, ist ein eigenes Thema; wir haben es im Beitrag zu Cookies, Consent und TDDDG auseinandergenommen.
Die zweite Falle sitzt im Cache. Liefert der Server ein Set-Cookie auf einer Antwort aus, die ein CDN oder ein anderer geteilter Cache speichern darf, kann im schlimmsten Fall der nächste Besucher die gecachte Antwort samt fremdem Cookie bekommen. Antworten mit Cookie gehören deshalb als private oder no-store markiert.
So sieht das im Check aus
Der Check liest die Set-Cookie-Header der Startseite und prüft für jedes Cookie Secure, HttpOnly und SameSite. SameSite=None ohne Secure ist ein eigener Befund, ebenso ein Cookie auf einer Antwort, die geteilte Caches speichern dürfen. Cookies, die erst nach dem Login oder im Checkout gesetzt werden, sieht er nicht. Die prüfst du in den Entwicklerwerkzeugen deines Browsers, Reiter „Anwendung“ beziehungsweise „Storage“, und das lohnt sich bei jedem Shop mindestens einmal pro Release.
Check 4: Info-Leaks. Liegen Quellcode oder Zugangsdaten offen im Netz?
Diese Kategorie enthält die Angriffe, die keinen Exploit brauchen. Ein Deployment per git pull auf dem Webserver, ein Vhost, dessen Document Root das Repository ist, und schon liegt /.git/HEAD öffentlich im Netz. Wer das findet, lädt mit frei verfügbaren Werkzeugen das komplette Repository nach, inklusive Historie. Darin stehen Datenbankzugänge, API-Schlüssel, manchmal private Keys.
Wie oft das passiert, hat Truffle Security 2023 gemessen: Von den Top-1-Million-Websites hatten 4.500 ein öffentlich erreichbares .git-Verzeichnis, darunter Hunderte gültige Zugangsdaten, 45 Prozent davon AWS- und GitHub-Credentials. Eine Site lieferte den privaten Schlüssel ihres TLS-Zertifikats aus. Dieselbe Logik gilt für .env-Dateien, die Laravel, Symfony, Node- und Shopware-Projekte für Konfiguration und Secrets nutzen: Liegt sie im Webroot und ist der Server nicht angewiesen, versteckte Dateien zu sperren, antwortet er mit HTTP 200 und dem Datenbankpasswort.
Zwei Leaks brauchen nicht einmal eine Datei. Ein Debug-Modus, der in Produktion an geblieben ist, zeigt Stacktraces, Konfiguration und manchmal Umgebungsvariablen: der Symfony-Profiler, die Laravel Debugbar, ein Vite-Dev-Server oder ein Next.js-Dev-Build auf der Live-Domain. Und geheime Schlüssel landen erstaunlich leicht im ausgelieferten HTML oder JavaScript, etwa ein Stripe-Live-Key oder ein OpenAI-Token, den jemand fürs Frontend „nur kurz“ eingebaut hat. Was im Quelltext steht, kann jeder kopieren.
Dazu kommen die leiseren Leaks. Ein Server: nginx/1.18.0 oder X-Powered-By: PHP/7.4 sagt einem Scanner, welche bekannten Lücken er probieren soll. Ein aktives Directory-Listing zeigt Verzeichnisinhalte, die nie für Besucher gedacht waren, Backups und Uploads inklusive. Eine offene Apache-Statusseite oder eine vergessene phpinfo()-Seite verrät Pfade, Module und Versionen. Und die HTTP-Methode TRACE spiegelt die Anfrage samt Headern zurück; sie hat auf einem Produktionsserver nichts verloren.
Der Fix ist in jedem Webserver ein paar Zeilen lang. Für nginx:
# Alle versteckten Dateien und Verzeichnisse sperren, .well-known bleibt erreichbar
location ~ /\.(?!well-known) { deny all; }
# Versionsnummer aus dem Server-Header nehmen
server_tokens off;
# X-Powered-By kommt von PHP selbst: in der php.ini expose_php = Off
Danach gehört jeder Zugang, der jemals in einer öffentlich erreichbaren Datei stand, ausgetauscht. Das Sperren allein hilft nicht, wenn die Datei vorher schon abgerufen wurde, und davon musst du ausgehen.
Zwei Dateien in dieser Kategorie sind erwünscht. robots.txt kennt jeder. /.well-known/security.txt nach RFC 9116 ist der standardisierte Ort, an dem du sagst, wohin Sicherheitsforscher eine gefundene Lücke melden sollen; Pflichtfelder sind Contact und Expires. Wer diese Datei hat, bekommt Hinweise, bevor sie zu Vorfällen werden.
So sieht das im Check aus
Die schweren Befunde zuerst: Erreichbare /.git/HEAD, /.git/config oder /.env, ein offenes Directory-Listing, ein aktiver Debug-Modus und geheime Schlüssel im Seitenquelltext (private Keys, Stripe-Live-Keys, GitHub-, Slack-, Anthropic- und OpenAI-Tokens) sind Fehler. Bei den sensiblen Dateien bewertet der Check nur Statuscode und Content-Type, den Inhalt liest er nie. Warnungen gibt es für einen Server-Header mit Versionsnummer, ein erreichbares /.DS_Store, eine offene Apache-Statusseite oder phpinfo()-Seite und aktives TRACE. robots.txt läuft als Hinweis. Eine gültige security.txt zählt als bestanden; fehlt sie oder ist ihr Inhalt ungültig, gibt es einen Hinweis.
Check 5: Inhalt & Skripte. Lädt deine Seite unsichere oder veraltete Dateien?
Deine Seite ist nur so sicher wie das, was sie nachlädt. Drei Dinge stehen im ausgelieferten HTML für jeden lesbar: Ressourcen, die über http:// eingebunden sind, obwohl die Seite per HTTPS läuft, externe Skripte ohne Integritätsschutz und, oft im Dateinamen, die Version der Bibliotheken, die du einsetzt.
Mixed Content ist das älteste der drei Probleme. Ein Bild über HTTP ist ärgerlich, ein Skript über HTTP ist gefährlich, denn wer im Netzwerkpfad sitzt, kann es austauschen, und es läuft dann mit allen Rechten deiner Seite. Moderne Browser blockieren aktive Mixed-Content-Ressourcen inzwischen, was bedeutet, dass die Funktion still ausfällt. Beides ist ein Grund, die Einbindung zu reparieren.
Das zweite Problem ist das Vertrauen in fremde CDNs. Im Juni 2024 hat die Firma Sansec dokumentiert, dass über 100.000 Websites ein Skript einbanden, das Schadcode an ausgewählte Besucher auslieferte. Die Domain polyfill.io, von der sie seit Jahren eine Kompatibilitätsbibliothek luden, hatte im Februar 2024 den Besitzer gewechselt, und der neue Betreiber manipulierte den Code. Die Betreiber der betroffenen Seiten hatten nichts geändert. Sie hatten einem Script-Tag vertraut, das irgendwann mal jemand eingebaut hatte.
Dagegen gibt es Subresource Integrity (SRI). Du gibst beim Einbinden den Hash der erwarteten Datei an, und der Browser führt das Skript nur aus, wenn der Inhalt dazu passt:
<script src="https://cdn.example.com/lib.min.js"
integrity="sha384-…"
crossorigin="anonymous"></script>Ändert jemand die Datei auf dem CDN, passt der Hash nicht mehr, und das Skript läuft nicht. SRI funktioniert nur für Dateien, die sich nicht ändern sollen, also versionierte Bibliotheken. Für Tag-Manager, Analytics-Loader oder Chat-Widgets, die sich laufend selbst aktualisieren, greift es nicht. Dort bleibt dir, die Zahl solcher Skripte klein zu halten und sie in der CSP auf genau diese Hosts zu beschränken. Oder du hostest die Bibliothek selbst, was bei einer versionierten Datei ohnehin die bessere Lösung ist.
Veraltete Bibliotheken: der billigste Befund für einen Scanner
Das dritte Problem ist das, nach dem Massen-Scanner am liebsten suchen, weil es keinen eigenen Aufwand braucht. Die Versionsnummer steht im Pfad (jquery-1.12.4.min.js, bootstrap@3.3.7), im Kommentar am Dateianfang oder bei WordPress im generator-Meta-Tag. Der Rest ist eine Datenbankabfrage. Werkzeuge wie retire.js machen seit Jahren nichts anderes, und dieselbe Abfrage kann jeder Angreifer automatisieren.
Wie verbreitet das Problem ist, zeigt jQuery. Laut W3Techs läuft jQuery auf 64,4 Prozent aller Websites, und von diesen Seiten nutzen 17,0 Prozent noch Version 1 und 4,2 Prozent Version 2 (Stand 27. Oktober 2026). Beide Release-Linien bekommen laut endoflife.date keine Updates mehr.
Zwei Beispiele. Für jQuery 1.12.4, die letzte Version der 1er-Linie, führt OSV.dev vier bekannte Lücken, darunter die XSS-Lücke CVE-2020-11022, alle mit dem Schweregrad „Moderate“. Für AngularJS 1.8.3, die allerletzte AngularJS-Version überhaupt, führt OSV.dev zehn Einträge, darunter zwei mit „High“, etwa eine XSS-Lücke im Paket angular. Der Support für AngularJS endete laut endoflife.date zu AngularJS am 31. Dezember 2021, einen offiziellen Fix gibt es also nicht mehr.
Eine bekannte Lücke in einer Bibliothek heißt nicht automatisch, dass sie auf deiner Seite ausnutzbar ist. Die jQuery-XSS-Lücken greifen etwa nur, wenn ungeprüftes HTML aus fremder Quelle durch bestimmte jQuery-Funktionen läuft. Für die Vorsortierung spielt das keine Rolle: Der Scanner sieht nur die Version und probiert es. Die Lösung ist das Update auf eine gepflegte Version. Die Versionsnummer aus dem Dateinamen zu entfernen, versteckt das Problem nur.
So sieht das im Check aus
Lädt die HTTPS-Startseite Dateien über http://, ist das eine Warnung. Externe Skripte ohne integrity-Attribut laufen als Hinweis, denn nicht jedes Skript lässt sich sinnvoll mit SRI absichern.
Zurück zur Zeile aus dem Einstieg. Zeigt deine Startseite die exakte Version von jQuery, Bootstrap, AngularJS, Vue, React oder WordPress, gleicht der Check sie mit OSV.dev, endoflife.date und WordPress.org ab. Ein Fehler ist eine bekannte Lücke mit dem Schweregrad High oder Critical in OSV.dev oder eine WordPress-Version, die WordPress.org als „insecure“ markiert. Andere bekannte Lücken, eine Version ohne Sicherheitsupdates (End of Life) oder ein verfügbares Update derselben Release-Linie (bei WordPress: eine Version, die WordPress.org als veraltet führt) sind eine Warnung. Ist keine Version sichtbar, gibt es einen Hinweis.
Nach diesen Regeln ist AngularJS 1.8.3 ein Fehler. jQuery 1.12.4 ist nur eine Warnung, weil keine seiner bekannten Lücken als High eingestuft ist. Im Score zählen Warnung und Fehler gleich, nur der Fehler kann die Note bei C deckeln. Für die Vorsortierung macht das keinen Unterschied.
Check 6: E-Mail-Absender. Kann jemand Phishing-Mails in deinem Namen verschicken?
Dieser Check hat mit deiner Website scheinbar nichts zu tun, und er ist trotzdem der, bei dem der Schaden am direktesten bei deinen Kunden landet. Ohne drei DNS-Einträge kann jeder Mailserver der Welt eine Mail mit rechnung@deine-domain.de als Absender verschicken, und für den Empfänger sieht sie echt aus. Gefälschte Rechnungen, geänderte Bankverbindungen, „Ihr Konto wurde gesperrt“: Das Muster ist bekannt, und die Domain, in deren Namen es passiert, trägt den Reputationsschaden. Und weil die gefälschten Mails bei deinen Kunden ankommen und nie bei dir, bleibt dieser Befund oft lange unbemerkt.
SPF (RFC 7208) ist ein TXT-Eintrag, der auflistet, welche Server für deine Domain senden dürfen. DKIM (RFC 6376) signiert jede ausgehende Mail kryptografisch, der öffentliche Schlüssel liegt im DNS unter einem Selektor. DMARC verbindet beides mit einer Policy: Was soll ein Empfänger mit Mails tun, die SPF und DKIM nicht bestehen? p=none heißt zustellen und nur melden. Erst p=quarantine oder p=reject sortiert Fälschungen aus.
DMARC ist seit Mai 2026 mit RFC 9989 als Proposed Standard auf dem IETF-Standards-Track und löst das RFC 7489 von 2015 (Status „Informational“) ab; bestehende v=DMARC1-Einträge funktionieren weiter.
Die großen Postfachanbieter haben das Thema vom Soll zum Muss gemacht. Google und Yahoo verlangen seit Februar 2024 von Massenversendern SPF, DKIM und mindestens ein DMARC mit p=none. Google zieht die Grenze bei mehr als 5.000 Mails pro Tag an Gmail-Adressen (Google-Senderrichtlinien) und verschärft die Durchsetzung seit November 2025 bis hin zu Zurückweisungen (Google zur Durchsetzung). Microsoft zog im Mai 2025 für Outlook.com nach und weist nicht konforme Mails von Großversendern mit 550 5.7.515 Access denied ab (Microsoft Tech Community).
Ein Shop mit großem Newsletter-Verteiler kann diese Schwelle erreichen. Und auch unterhalb davon entscheiden dieselben drei Einträge darüber, ob deine Bestellbestätigung im Posteingang oder im Spam landet.
Drei Einträge, die den Zustand „niemand darf in meinem Namen senden, außer meinem Mailanbieter“ herstellen:
# SPF: nur Google Workspace darf senden, alles andere hart ablehnen
deine-domain.de. TXT "v=spf1 include:_spf.google.com -all"
# DKIM: öffentlicher Schlüssel unter dem Selektor des Anbieters
google._domainkey.deine-domain.de. TXT "v=DKIM1; k=rsa; p=…"
# DMARC: Fälschungen in Quarantäne, Reports an dich
_dmarc.deine-domain.de. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@deine-domain.de"
Die richtige Reihenfolge: SPF und DKIM setzen, DMARC mit p=none und Reporting-Adresse anlegen, zwei bis vier Wochen die Reports lesen, bis jeder legitime Sender (Shop, Newsletter-Tool, CRM, Ticketsystem) sauber authentifiziert ist, dann auf quarantine und später auf reject gehen. Wer sofort auf reject stellt, ohne die Reports zu kennen, blockiert gern das eigene Rechnungssystem.
So sieht das im Check aus
Gelesen wird ausschließlich aus dem öffentlichen DNS deiner Domain. Drei Warnungen sind möglich: fehlendes SPF, fehlendes DMARC und ein DMARC mit p=none. Steht hier p=none, hast du DMARC eingerichtet, aber noch keine einzige Fälschung aufgehalten. DKIM sucht der Check unter den drei gängigen Selektoren default, google und selector1; nutzt dein Anbieter einen anderen, erscheint das nur als Hinweis. DNSSEC und die tatsächliche Zustellung prüft er nicht. Wer nur die Domain und nicht die ganze Website prüfen will, nimmt den schlankeren SPF-, DKIM- und DMARC-Check.
Extra: der Port-Check, nur für deine eigene Domain
Die sechs Checks lesen, was dein Webserver ausliefert. Ein Angreifer schaut zusätzlich, welche Türen auf derselben Adresse sonst noch offen stehen. Eine direkt erreichbare Datenbank, ein Remote-Desktop-Zugang oder ein FTP-Server mit Klartext-Passwörtern sind Ziele für automatisierte Login-Versuche. Wie oft das passiert, kannst du auf einem Linux-Server mit offenem SSH selbst nachzählen, etwa mit sudo journalctl -u ssh -u sshd --since today | grep -c "Invalid user". Die Zahl ist eine Untergrenze, denn sie zählt nur Versuche mit Benutzernamen, die es nicht gibt.
Der Port-Check versucht auf 16 üblichen Ports einen Verbindungsaufbau: Web (80, 443, 8080, 8443), Mail (25, 465, 587, 110, 143, 993, 995), FTP (21), SSH (22), MySQL (3306), PostgreSQL (5432) und Remote Desktop (3389). Es bleibt beim Verbindungsaufbau mit zwei Sekunden Timeout: kein Login, keine Anfrage an den Dienst.
Die Bewertung ist streng. Offene Ports 80 und 443 sind bestanden, das ist schließlich deine Website. Offene Ports 21, 22, 3306, 5432 und 3389 sind ein Fehler, jeder andere offene Port eine Warnung. Dass SSH als Fehler zählt, wird manchen Admin ärgern. Ich halte es für richtig, und der Grund heißt regreSSHion: Im Juli 2024 veröffentlichte Qualys eine Lücke in OpenSSH (CVE-2024-6387), über die sich auf glibc-basierten Linux-Systemen Code ausführen ließ, ohne dass sich jemand anmelden musste. Schlüssel statt Passwort hilft dagegen nicht, weil die Lücke vor jeder Anmeldung greift. SSH gehört hinter ein VPN oder eine IP-Allowlist.
Das Ergebnis zählt weder zum Score noch zur Note und geht nur an eine Adresse der geprüften Domain oder einer übergeordneten, bis hinauf zur registrierbaren Domain: Für www.beispiel.de reicht info@beispiel.de. Mit dem Code aus dieser Mail erscheinen die Ports auch im Report.
Wie sich der Check gegen Missbrauch schützt
Ein Werkzeug, das auf Zuruf beliebige URLs abruft, ist selbst ein Angriffsziel. Das klassische Muster heißt Server-Side Request Forgery: Jemand trägt statt einer Website eine interne Adresse wie 192.168.0.1 ein und lässt den Scanner das Netz seines Betreibers abfragen. Die raffiniertere Variante ist eine Domain, die bei der Prüfung auf eine öffentliche IP zeigt und Millisekunden später auf eine interne (DNS-Rebinding).
Der Check sperrt deshalb private und interne IP-Adressen. Er löst den Namen einmal auf und nagelt den ganzen Scan auf diese IP fest, sodass eine nachträglich umgebogene DNS-Antwort ins Leere läuft. Und er prüft jede Weiterleitung einzeln, bevor er ihr folgt: Adresse zerlegen, auflösen, IP kontrollieren. Gegen Massenabfragen gelten Limits: 8 Scans pro Minute pro Besucher-IP, 20 Scans pro Stunde pro Zieldomain, höchstens 2 parallele Scans pro Besucher. Die Antwortgröße ist auf 512 KB begrenzt, jeder Abruf hat ein Timeout. Für einen erneuten Check nach dem Fix reicht das bequem, für eine Scan-Kampagne über fremde Domains ist es unbrauchbar.
Was die Note bedeutet
Der Score ist bewusst einfach gebaut. Jede Prüfung zählt gleich viel, eine versteckte Gewichtung gibt es nicht. Der Score ist der Anteil bestandener Prüfungen an allen bewerteten (bestanden, Warnung oder Fehler), gerundet auf 0 bis 100. Hinweise zählen nicht mit. Daraus wird die Note: A ab 90 Punkten, B ab 80, C ab 65, D ab 50, darunter F.
Dazu kommt eine zweite Regel: Schon ein einziger Fehler begrenzt die Note auf C. Ein Rechenbeispiel: 20 bewertete Prüfungen, 17 bestanden, ergibt 85 Punkte und damit ein B. Ist unter den drei übrigen ein Fehler, bleibt es bei 85 Punkten, die Note ist trotzdem C. Eine Website mit perfekten Headern und einer öffentlichen .env-Datei ist keine B-Website, weil ein Angreifer nicht den Durchschnitt deiner Konfiguration sucht, sondern die eine Stelle, die reicht. Die Zusammenfassung nennt deshalb den dringendsten Befund gesondert unter „Zuerst beheben“.
Was ein Außen-Check grundsätzlich nicht sieht, gehört genauso in den Befund. Er prüft nur die Startseite: Unterseiten, Login-Bereiche, Checkout und APIs bleiben außen vor. Versionen gleicht er nur für die sechs genannten Bibliotheken und Systeme ab, und nur, wenn die Seite sie verrät; Shop-, Plugin- und Server-Versionen prüft er nicht auf Lücken. Und er greift nichts an. Für Shops, Kundenportale und alles mit sensiblen Daten gehört deshalb zusätzlich ein Penetrationstest auf die Liste, der die Anwendung selbst angreift.
Rechtlich ist die Grundkonfiguration kein Extra. Art. 32 DSGVO verlangt geeignete technische Maßnahmen unter Berücksichtigung des Stands der Technik, und verschlüsselte Verbindungen sowie eine gepflegte Server-Konfiguration gehören dazu. Nennt die Datenschutzerklärung deiner Website Verschlüsselung und Schutzmaßnahmen, zeigt der Check, ob das für den von außen sichtbaren Teil stimmt.
Daraus folgt die Reihenfolge: erst die Grundkonfiguration, dann der Pentest. Wer einen Penetrationstest auf eine Website bestellt, deren .git öffentlich ist, kennt die ersten zwanzig Minuten des Berichts schon.
Vom Befund zum Fix: drei Wege
Je nachdem, wer bei dir Server und DNS betreut, gibt es drei realistische Wege. Hat dein Unternehmen eigene Admins oder einen Hoster mit Zugriff auf die Konfiguration, reicht der Report: Zu jedem Befund steht dort die Empfehlung, Header und Redirects sind wenige Zeilen, DNS-Einträge drei Zeilen, und danach prüfst du einfach erneut. Sitzt ein CDN mit Seiten-Cache davor, kann es kurz noch die alte Antwort ausliefern.
Fehlt ein eigenes Ops-Team, setzen wir die Fixes an Webserver, CDN, Shop und DNS um und belegen das Ergebnis mit einem neuen Check. Sicherheits-Patches und Updates veralteter Komponenten gehören bei uns zu Wartung und Support, Server und Infrastruktur zu Hosting und Skalierung. Und wo ein Shop oder ein Kundenportal mit echten Daten dahinter liegt, vermitteln wir einen spezialisierten Partner für den Penetrationstest, stimmen den Umfang ab und schließen danach die gefundenen Lücken.
Score und Note siehst du ohne jede Angabe. Befunde und Empfehlungen schaltet deine geschäftliche E-Mail-Adresse frei. Der erste Schritt kostet dich also nur eine URL: Website prüfen, Score ansehen, und dann weißt du, was die Gegenseite bereits weiß.
Häufige Fragen: Website-Sicherheit prüfen
Welcher Befund ist am dringendsten?
Alles, was im Check als Fehler erscheint; den ersten davon nennt die Zusammenfassung unter „Zuerst beheben“. Fehler sind:
- kein HTTPS oder ein ungültiges oder in weniger als 7 Tagen ablaufendes Zertifikat
- ein öffentlich erreichbares
.git-Verzeichnis, eine erreichbare.env-Datei oder ein offenes Directory-Listing - ein aktiver Debug-Modus oder ein geheimer Schlüssel im Quelltext
- eine Bibliothek mit schwerer bekannter Lücke oder eine WordPress-Version, die WordPress.org als unsicher markiert
Bei offenen Dateien und Schlüsseln gehören anschließend alle betroffenen Zugangsdaten ausgetauscht.
Wie kann ich meine Website-Sicherheit kostenlos prüfen?
Mit einem Außen-Check, der nur liest, was dein Server jedem Besucher ausliefert: HTTPS und Zertifikat, Security-Header, Cookie-Flags, offene Dateien, Mixed Content, sichtbare Bibliotheksversionen und die DNS-Einträge SPF, DKIM und DMARC. Unser Security Check zeigt Score und Note sofort, ohne Login und ohne Angriff.
Was bekomme ich ohne und mit E-Mail-Adresse?
Ohne Angaben siehst du sofort Score, Note, die Zahl der bestandenen Prüfungen, Warnungen, Fehler und Hinweise sowie alle Prüfpunkte mit Status; die Details sind gesperrt. Mit deiner geschäftlichen E-Mail-Adresse und der Zustimmung zur Datenschutzerklärung schaltest du jede Prüfung mit Befund und Empfehlung sofort frei, der komplette Report kommt in wenigen Minuten per Mail. Pflicht ist nur die E-Mail, Vorname, Nachname und Telefon sind freiwillig. Innerhalb eines Werktags meldet sich jemand aus unserem Team, einmal.
Darf ich mit dem Security Check fremde Websites prüfen?
Technisch ja: Der Web-Check nutzt nur öffentlich erreichbare Adressen und öffentliche DNS-Einträge. Das Ergebnis des Port-Checks geht aber nur an eine E-Mail-Adresse der geprüften Domain, und Limits pro IP und pro Zieldomain machen das Tool für Massenscans ungeeignet.
Ist ein Website-Security-Check dasselbe wie ein Penetrationstest?
Nein. Ein Penetrationstest greift eine Anwendung gezielt an: Logins, Schnittstellen, Rechte, Eingaben. Ein Security-Check bewertet die öffentliche Konfiguration. Beides ergänzt sich, und die Grundkonfiguration sollte vor dem Pentest stimmen.
Wie oft sollte ich die Website-Sicherheit prüfen?
Nach jedem Deployment, das Server, CDN, DNS oder eingebundene Bibliotheken berührt, und sonst mindestens quartalsweise. Zertifikate laufen inzwischen kürzer, Plugins setzen ungefragt Cookies und Skripte, für alte Bibliotheksversionen kommen neue Lücken dazu, und DNS-Einträge ändern sich, wenn ein neues Newsletter- oder CRM-Tool dazukommt.