Methode
Die technischen Einzelheiten hinter So prüfen wir: was ein Check genau lädt und mit welchen Grenzen, wie sich die Punkte zusammensetzen, woher die Daten kommen und welche Limits gelten.
1. Was ein Check liest
Ein Check besteht aus genau diesen Schritten. Mehr passiert nicht.
- Ein GET-Aufruf Ihrer Adresse, wie bei jedem normalen Seitenbesuch. Wir lesen die Antwort-Header und das ausgelieferte HTML, höchstens 800 KB, und warten höchstens 8 Sekunden.
- Weiterleitungen verfolgen wir selbst, höchstens 5. Jede Station prüfen wir vorher darauf, dass sie nicht auf eine interne oder private Adresse zeigt.
- Die JavaScript-Dateien, die die Seite selbst einbindet, also Skripte aus
<script src>undmodulepreload. Diese Dateien lädt jeder Browser beim Seitenbesuch ebenfalls. Wir laden nur Dateien derselben Domain, auch von Subdomains wie cdn.ihre-firma.de, zuerst höchstens 10 Dateien, je Datei 2 MB und zusammen 6 MB, in höchstens 6 Sekunden. Leitet eine Skript-Adresse weiter, folgen wir nicht. Jede Adresse prüfen wir vorher darauf, dass sie nicht intern oder privat ist. - Nachgeladene Teile, die diese Dateien beim Wechsel auf eine Unterseite holen, auch Teile, die selbst weitere nachladen, und bei Next.js die Teile aller Seiten aus dem Build-Manifest: höchstens 40 weitere Dateien in bis zu drei Runden, zusammen in höchstens 5 Sekunden und innerhalb derselben 6 MB.
- Konfigurationsdateien derselben Domain, die der Code beim Start selbst abruft, etwa
/config.jsonoder/api/config: nur Adressen, die als fester Text in einemfetch-Aufruf stehen und nach Konfiguration aussehen, höchstens 4, nur lesend. - Die Stylesheets der Seite von derselben Website, höchstens 3, für den Datenschutz-Check (etwa Google Fonts per
@import). - Ein Aufruf über http:// derselben Adresse, nur um zu sehen, ob er auf https umleitet.
- Die Datei
/.well-known/security.txt(RFC 9116), die für Sicherheitsmeldungen gedacht ist. - Ein TLS-Handschlag auf Port 443, derselbe, den jeder Browser macht. Daraus lesen wir Gültigkeit, Aussteller, Ablaufdatum und Protokoll des Zertifikats.
- Abfragen im öffentlichen DNS: SPF und DMARC (bei einer Subdomain wie shop.firma.de auch bei firma.de), die SPF-Einträge, die Ihr Eintrag einbindet, MX, MTA-STS und DANE, CAA und die CNAME-Kette der Adresse. Dabei sprechen wir nicht mit Ihrem Server.
- Eine DNSSEC-Abfrage über DNS-over-HTTPS bei Cloudflare. Dorthin geht nur der Domainname.
- Abfragen bei OSV.dev, CISA, FIRST, endoflife.date und WordPress.org für erkannte Software. Dorthin gehen nur Paketnamen, Versionen und CVE-Nummern, nie Ihre Adresse.
Bilder, Stylesheets und Skripte fremder Domains laden wir nicht. Pfade, die die Seite nicht selbst einbindet oder abruft, probieren wir nicht aus, mit Ausnahme der security.txt. Finden wir einen Schlüssel, benutzen wir ihn nie. Im Bericht stehen Art und Fundstelle, der Wert nur gekürzt, etwa sk_live_…9f2A. Den vollständigen Wert zeigen und speichern wir nie.
Plattformen erkennen
Im Feld platforms des Berichts steht, worauf eine App läuft. Wir nennen eine Plattform nur bei einer eindeutigen Spur. Werkzeuge wie Cursor, Claude Code oder Codex hinterlassen keine eigene Spur. Damit gebaute Apps erscheinen etwa als Vite oder Next.js.
| Plattform | Erkannt |
|---|---|
| Lovable, Bolt, v0, Replit, Base44 | an der Hosting-Domain, etwa *.lovable.app, oder an eingebundenen Plattform-Skripten |
| Vercel, Netlify | an den Antwort-Headern |
| Next.js, Vite | an den Pfaden der Skripte im HTML |
| Supabase, Firebase | an Adressen in den JavaScript-Dateien |
2. So entsteht die Note
Jeder Check startet mit 10 Punkten. Für jeden vorhandenen Schutz-Header kommen Punkte dazu, zusammen höchstens 100. Danach ziehen wir für andere Funde ab. Das Ergebnis liegt immer zwischen 0 und 100.
Punkte für Schutz-Header
| Header | Punkte | Fehlt er, ist das eine |
|---|---|---|
| Grundwert | 10 | immer |
| Content-Security-Policy | +25 | Warnung |
| Strict-Transport-Security (HSTS) | +20 | Warnung |
| X-Frame-Options oder frame-ancestors in der CSP | +15 | Hinweis |
| X-Content-Type-Options | +10 | Hinweis |
| Referrer-Policy | +10 | Hinweis |
| Permissions-Policy | +10 | Hinweis |
| Höchstwert | 100 |
Gezählt wird, ob ein Header vorhanden ist. Bei der Content-Security-Policy zählt auch der Inhalt: Regelt sie keine Skripte, erlaubt sie 'unsafe-inline' ohne Nonce oder Hash oder Skripte von beliebigen Adressen (*, https:, data:), gibt es statt 25 nur 10 Punkte und den Hinweis header.csp.weak. Mit 'strict-dynamic' gilt sie als stark. Mehrere Richtlinien gelten zusammen, eine starke genügt.
Abzüge
| Fund | Abzug |
|---|---|
| Keine HTTPS-Verbindung | minus 20, die Note ist dann immer F |
| Geheimer Schlüssel im Quelltext oder in den JavaScript-Dateien, etwa Supabase service_role, OpenAI oder Stripe | minus 40 je Art von Schlüssel |
| Adresse, die Fremde übernehmen können (verwaister CNAME) | minus 40 |
| Version mit bekannten Lücken, die laut CISA aktiv ausgenutzt werden | minus 25 je Fund |
| Version mit bekannten Lücken | minus 8 je Fund, höchstens minus 20 |
| Muster eines Geheimnisses im HTML | minus 25 je Art von Schlüssel |
| Anderer Code-Fund mit Warnung (gemischte Inhalte, Fehlerausgabe, KI-Aufruf direkt aus dem Browser, geheim benannte Variablen) | minus 10 |
| Code-Fund als Hinweis (Google-API-Schlüssel, SRI, Source Maps, sensible Pfade, Supabase mit öffentlichem Schlüssel) | minus 3 |
| Zertifikat, E-Mail-Schutz oder fehlende Weiterleitung auf https, Warnung (auch SPF mit mehr als 10 Abfragen) | minus 5 |
| Zertifikat, E-Mail-Schutz oder fehlende Weiterleitung auf https, Hinweis | minus 2 |
Ohne Abzug, aber im Bericht: eine sichtbare Server-Version, ein gesetzter X-Powered-By-Header, Cookies ohne Secure oder HttpOnly, alle Datenschutz-Befunde und die DNS-Hygiene (CAA, DNSSEC, security.txt, MTA-STS). Die Note misst die Angriffsfläche. Ein Zertifikat, das in weniger als 14 Tagen abläuft, ist eine Warnung, unter 30 Tagen ein Hinweis.
Notengrenzen
| Note | Punkte |
|---|---|
| A | 90 bis 100 |
| B | 75 bis 89 |
| C | 60 bis 74 |
| D | 40 bis 59 |
| E | 20 bis 39 |
| F | unter 20, oder kein HTTPS |
Jeder Fund bedeutet „möglicherweise betroffen“, kein Beweis. 100 Punkte heißen, dass keiner unserer Prüfpunkte anschlägt. Das beweist nicht, dass die Seite sicher ist. Was hinter der Oberfläche liegt, etwa Datenbanken und Zugriffsrechte, sieht erst ein Security Audit.
3. Schlüsselsuche
Im HTML, in eingebetteten Daten wie __NEXT_DATA__, in den JavaScript-Dateien und in den Konfigurationsdateien suchen wir nach geheimen Schlüsseln und Zugangsdaten, unter anderem: Supabase-Generalschlüssel (service_role), geheimer Supabase-Schlüssel (sb_secret), OpenAI, Anthropic, OpenRouter, Groq und xAI, Stripe (sk_live, rk_live), AWS, GitHub, Slack, SendGrid, Twilio, Webhook-Adressen von Slack, Discord, Teams und Zapier, Datenbank-Zugänge mit Passwort, private Schlüssel (PEM). Dazu kommen über 100 weitere Anbieter aus den Regeln des Open-Source-Projekts gitleaks. Mit atob() Base64-kodierte Werte lesen wir dekodiert mit. Google-API-Schlüssel melden wir nur als Hinweis, weil sie oft absichtlich öffentlich sind. Dazu melden wir, wenn eine App eine KI-Schnittstelle direkt aus dem Browser aufruft, wenn Build-Variablen mit VITE_, NEXT_PUBLIC_, REACT_APP_ oder EXPO_PUBLIC_ Wörter wie SECRET oder PASSWORD im Namen tragen und wenn die Dateien auf Quellcode-Karten verweisen. Spricht eine App Supabase mit dem öffentlichen Schlüssel an, geben wir einen Hinweis: Sicher ist das nur mit Zugriffsregeln (Row Level Security) auf jeder Tabelle. Ob sie stimmen, sehen wir von außen nicht.
Gemeldet werden Art und Fundstelle, der Wert nur gekürzt, etwa sk_live_…9f2A oder AKIA…MPLE. Den vollständigen Wert zeigen wir nie.
4. Datenquellen
Technik erkennen
Welche Software eine Seite nutzt, erkennen wir mit den Regeln von webappanalyzer (einem gepflegten Fork der Wappalyzer-Regeln) und den Erkennungsmerkmalen von Retire.js, aus Antwort-Headern, Cookies, HTML und den geladenen Skripten.
OSV.dev, CISA KEV und FIRST EPSS
Rund 50 verbreitete JavaScript-Bibliotheken, etwa jQuery, Bootstrap, React, Vue, Angular, Next.js, Lodash, Moment, Axios, Chart.js, DOMPurify, TinyMCE, gleichen wir live mit OSV.dev ab, einer offenen Datenbank für bekannte Schwachstellen, und zeigen pro Bibliothek bis zu 6 Einträge. Steht eine Lücke im Katalog der US-Behörde CISA für aktiv ausgenutzte Schwachstellen, ist der Befund kritisch. Die Wahrscheinlichkeit einer Ausnutzung in den nächsten 30 Tagen nennen wir nach FIRST EPSS. Antwortet OSV.dev nicht innerhalb von 4,5 Sekunden, nutzen wir unsere eigene Liste und schreiben das dazu.
Supportende
Ob eine erkannte Version noch Sicherheits-Updates bekommt, etwa bei PHP, WordPress, nginx oder Node.js, prüfen wir über endoflife.date. Unsichere WordPress-Kernversionen nennt WordPress.org selbst.
Schlüsselmuster
Neben eigenen Mustern nutzen wir die Regeln von gitleaks (MIT-Lizenz) ohne allgemeine und absichtlich öffentliche Muster. Jede Änderung prüfen wir an über 100 echten Seiten auf Fehlalarme und an einem Testparcours mit typischen Leck-Stellen.
Eigene Liste
Für Software ohne npm-Paket gilt eine kurze, feste Liste:
| Software | Gemeldet bei Version | Grund |
|---|---|---|
| PHP | vor 7.4 und vor 8.1 | außerhalb des Sicherheits-Supports |
| WordPress | vor 6.4 | ältere Kernversionen mit dokumentierten Lücken |
| jQuery | vor 3.5.0 | CVE-2020-11022 und CVE-2020-11023 |
| Bootstrap | vor 4.3.1 | CVE-2019-8331 |
| OpenSSL | vor 1.1.1 | sehr alte Reihe |
Versionen erkennen wir aus dem Server-Header, aus X-Powered-By, aus dem Generator-Tag und aus den Adressen eingebundener Dateien.
5. Limits
| Zugang | Checks pro Stunde |
|---|---|
| Ohne Anmeldung und ohne Schlüssel (Browser und MCP, je IP-Adresse) | 20 |
| Kostenloses Konto oder Schlüssel | 100 |
| Business | 2.000 |
Die REST-API braucht immer einen Schlüssel. Die Limits gelten je Stunde und sollen Missbrauch bremsen. Für jeden Check gelten feste Grenzen. Der Abruf darf 8 Sekunden dauern, der TLS-Handschlag 5 Sekunden. Wir lesen höchstens 800 KB HTML und folgen höchstens 5 Weiterleitungen. Von den JavaScript-Dateien laden wir höchstens 10, je Datei 2 MB und zusammen 6 MB, in höchstens 6 Sekunden.
Ohne bezahlten Plan enthält der Bericht Note, Punkte und die Zahl aller Befunde, vollständig aber nur 2 Befunde. Gekürzt wird auf unserem Server. Alle Befunde mit Anleitung enthält der Bericht ab Business.
Interne Adressen, localhost und Namen auf .local, .internal und .test prüfen wir nicht.