Regel-Katalog
Was der Vibe Code Rescue Scan prüft
Jede Prüfung des Rescue Scans hat einen stabilen, versionierten Code (z. B. RSC-SEC-014) und eine eigene Seite: was geprüft wird, warum es zählt und was zu tun ist. Der Katalog ist die offene Referenz hinter jedem Verdikt.
Eigene App kostenlos prüfenWie das Verdikt entsteht
Bis August 2026 stand hier eine Rechnung: gewichtete Dimensionen, Strafpunkte je Befund, Schwellen. Sie ist ersatzlos entfallen. Eine Zahl aus frei gewählten Gewichten sah nach Messung aus, war aber eine Meinung mit Nachkommastelle — und sie konnte einen belegten Befund hinter einem guten Mittelwert verstecken. Stattdessen gelten drei nachlesbare Regeln über Schwere und Belastbarkeit. Die Werte auf dieser Seite kommen direkt aus dem laufenden Code, nicht aus einer Doku, die veralten kann.
Schweregrad — wie schlimm es wäre
Vier Stufen. Sie sagen, was der Befund anrichtet, wenn er zutrifft. Reine Hinweise („Supabase erkannt“) zählen intern als Info und gehen weder in die Liste noch in das Verdikt ein.
- Kritischcritical
- Hochhigh
- Mittelmedium
- Niedriglow
Belastbarkeit — wie sicher wir es wissen
Abgeleitet aus der Prüfstufe, die den Befund erzeugt hat. Ein fehlender Header ist von außen zweifelsfrei belegt; eine Vermutung aus einer halb rekonstruierten Source Map ist es nicht. Ohne diese zweite Angabe stünden Beobachtung und Vermutung gleichberechtigt nebeneinander:
- bestätigtconfirmed
- hochhigh
- mittelmedium
Die drei Regeln, je Dimension
- Stopp: mindestens ein Befund mit Schweregrad „kritisch“ UND Belastbarkeit „bestätigt“. Beides zusammen — „bestätigt“ gibt es nur aus einem Lauf mit Domain-Nachweis oder mit Repo-Zugang. Das heißt ausdrücklich: Ein rein anonymer Außen-Scan sagt nie „Stopp“. Er kennt keinen Befund, den er selbst ausgelöst oder im Quelltext gelesen hätte.
- Iterate: sonst — mindestens ein Befund ab „hoch“ aufwärts, oder mindestens 3 Befunde mit Schweregrad „mittel“ in derselben Dimension, oder ein einzelner mittlerer Befund in Sicherheit oder Datenschutz. Ein einzelner mittlerer Befund ist in einem MVP normal; 3 in einem Bereich sind ein Muster. In den zwei Bereichen, die Vertrauen tragen, genügt aber schon einer: Neben einer anonym lesbaren Tabelle oder Tracking ohne Einwilligung können wir nicht „tragfähig“ sagen.
- Go: sonst. Befunde mit Schweregrad „niedrig“ kippen das grüne Licht nie — acht fehlende HTTP-Header sind kein kaputtes Fundament. Und zwei mittlere Befunde sind davon ausgenommen: „Content-Security-Policy fehlt“ und „HSTS-Header fehlt“ beschreiben eine fehlende zusätzliche Schutzschicht, keinen Defekt. Nicht gehärtet ist nicht dasselbe wie kaputt.
Das Gesamturteil ist das schlechteste Verdikt über die sechs Dimensionen. Befunde werden dabei nicht über Bereiche hinweg zusammengezählt: Die Schwelle soll ein Muster in EINEM Bereich erkennen. Befunde, die ein verbundenes Repository widerlegt hat, zählen nicht mehr mit.
Was nicht geprüft werden konnte, wird als „begrenzt prüfbar“ ausgewiesen und zeigt „—“, nie eine Null und nie eine geschönte Bestnote. Daneben steht die Prüftiefe in Zahlen: wie viele Prüfungen in eurem Fall anwendbar waren und wie viele davon tatsächlich liefen. Prüfungen, die für euch gar nicht gelten, verlassen den Nenner — Prüfungen, die wir nicht ausführen konnten, bleiben darin.
Methodik-Version 2026.18. Jede inhaltliche Regeländerung erhöht sie, damit ältere Ergebnisse einordenbar bleiben.
Sicherheit
Kein durchgängiges HTTPS
Prüft, ob die finale Antwort verschlüsselt ausgeliefert wird oder auf http endet.
HSTS-Header fehlt
Prüft, ob Strict-Transport-Security gesetzt ist und der erste Aufruf damit abgesichert wird.
Keine Content-Security-Policy
Prüft Header und Meta-Tag auf eine Content-Security-Policy als Schutzschicht gegen XSS.
MIME-Sniffing nicht unterbunden
Prüft, ob `X-Content-Type-Options: nosniff` das Erraten von Inhaltstypen verhindert.
Kein Clickjacking-Schutz
Prüft X-Frame-Options bzw. CSP `frame-ancestors` gegen das Einbetten in fremde Seiten.
CORS-Wildcard am öffentlichen Dokument
Erfasst `Access-Control-Allow-Origin: *` am HTML — allein keine Lücke, aber ein Prüf-Signal.
Server-Technologie preisgegeben
Erfasst Version-Header wie `X-Powered-By`, die gezielte Exploit-Suche erleichtern.
Cookies ohne Secure/HttpOnly
Prüft gesetzte Cookies auf die Flags Secure und HttpOnly.
Supabase-Client-Konfiguration sichtbar
Erfasst Projekt-URL und anon-Key im Bundle — erwartbar, aber Ausgangspunkt der Zugriffsprüfung.
Supabase service_role-Schlüssel im Client
Dekodiert JWTs im Bundle und meldet den Rollen-Claim `service_role`, der RLS vollständig umgeht.
Geheimschlüssel im ausgelieferten Code
Sucht Muster echter Geheimnisse (Stripe, AWS, GitHub, PEM) im HTML und in den Bundles.
Firebase-Backend erkannt
Erfasst Firebase-Konfiguration im Client — zulässig, entscheidend sind die Sicherheitsregeln.
.env-Datei öffentlich abrufbar
Ruft bekannte Env-Pfade ab und bestätigt Treffer inhaltlich anhand von KEY=VALUE-Zeilen.
.git-Verzeichnis öffentlich
Bestätigt ein ausgeliefertes `.git` über die Signaturen von `config` und `HEAD`.
Datenbank-Tabellen der anon-Rolle zugeteilt
Fragt mit dem von der App selbst veröffentlichten Client-Schlüssel den Schema-Endpunkt ab und listet die Tabellen, die der anon-Rolle zugeteilt sind — ohne einen Datensatz oder eine Zeilenzahl abzurufen. Zugeteilt heißt noch nicht lesbar: ob Zeilen herauskommen, entscheidet Row Level Security.
Datenbank-Tabellen anonym lesbar (nachgewiesen)
Beantwortet die eigentliche Frage: Kommen mit dem öffentlich ausgelieferten Schlüssel tatsächlich Zeilen heraus? Gezählt wird ausschließlich über den `Content-Range`-Header einer HEAD-Anfrage — es wird keine einzige Zeile abgerufen.
Google API-Schlüssel im Client
Erfasst Schlüssel im Format `AIza…` im ausgelieferten Code — bei Maps und Firebase vorgesehen, riskant ohne Domain-Beschränkung.
Datenbank-Zugangsdaten im Client sichtbar
Findet Connection-Strings mit eingebettetem Benutzer und Passwort im HTML oder in den Bundles.
Firestore-Collections anonym lesbar
Fragt die Collections, die die App selbst im Bundle nennt, mit dem öffentlichen Web-Schlüssel an — mit `mask.fieldPaths=__name__`, also nur Dokument-Namen, kein einziger Feldwert.
Datenbank-Funktionen für anonyme Aufrufer freigegeben
Listet die der anon-Rolle zugeteilten RPC-Funktionen aus der Schema-Beschreibung — gelesen, nicht aufgerufen.
Registrierung offen, Konten sofort bestätigt
Liest die anonym abrufbare Auth-Konfiguration: Selbstregistrierung offen und E-Mail-Bestätigung deaktiviert.
KI-API direkt aus dem Browser gerufen (statisch belegt)
Findet Endpunkte von KI-Anbietern im ausgelieferten Code. Mit passendem Schlüssel-Muster im selben Bundle `high`, ohne `medium`.
Browser schreibt direkt in die Datenbank
Findet Schreibaufrufe (`insert`, `update`, `upsert`, `delete`, Storage-Upload) im ausgelieferten Code bzw. in `use client`-Dateien.
Zugangsdaten fest im Browser-Code verglichen
Findet Vergleiche wie `password === "…"` gegen ein festes Literal im ausgelieferten Code.
Storage-Buckets öffentlich listbar
Prüft, ob Datei-Buckets ihre Objektliste anonym herausgeben.
Firebase-Datenbank anonym lesbar
Fragt den Realtime-Database-Endpunkt mit `shallow=true` ab: antwortet er mit Schlüsselnamen statt „permission denied“, ist die Datenbank offen.
Geschützter Bereich nur im Browser abgesichert
Erkennt Admin-/Konto-Routen, die der Client-Router kennt, deren Schutz aber ausschließlich als Bedingung im Bundle steht — wer die URL kennt, ist drin.
Rollenprüfung im Client-Bundle
Findet Rollenvergleiche wie `role === "admin"` im ausgelieferten JavaScript — im Browser beliebig manipulierbar.
Zugangstoken in localStorage
Beobachtet zur Laufzeit, ob ein JWT-artiger Wert in Web-Storage landet — per XSS auslesbar.
KI-API direkt aus dem Browser gerufen
Beobachtet Aufrufe an LLM-Anbieter aus dem Client — der dafür nötige Schlüssel liegt damit offen und jeder Besucher kann auf eure Rechnung generieren.
Backup- oder Datenbank-Dump öffentlich
Prüft typische Dump-/Backup-Pfade und bestätigt Treffer über SQL- bzw. Archiv-Signaturen.
Keine Permissions-Policy
Prüft, ob Kamera, Mikrofon und Standort per Header explizit eingeschränkt werden.
Keine Referrer-Policy
Prüft, ob ausgehende Links interne URLs samt Query an Dritte weitergeben.
Unverschlüsselte Inhalte auf HTTPS-Seite (aktiv / passiv)
Findet per `http://` eingebundene Ressourcen auf einer https-Seite und trennt aktive (Skripte, Frames, Stylesheets — vom Browser blockiert) von passiven (Bilder, Audio, Video — Warnung, kein Block).
Anmeldung ohne erkennbare Sperre
Sendet nach Ownership-Nachweis eine kleine Serie fehlerhafter Anmeldeversuche und prüft, ob überhaupt gebremst wird.
Admin-Bereich anonym erreichbar
Ruft entdeckte Verwaltungs-Pfade anonym auf und meldet, wenn Inhalt statt Weiterleitung zur Anmeldung kommt.
Kein SPF und kein DMARC — E-Mail-Fälschung ungeschützt
Prüft, ob die Domain mindestens einen SPF- oder DMARC-Eintrag im DNS hat, mit dem Empfänger gefälschte Mails erkennen können.
Kein DMARC-Eintrag
Prüft, ob zu einem vorhandenen SPF-Eintrag auch ein DMARC-Eintrag existiert, der festlegt, was mit gefälschten Mails passiert.
SPF-Eintrag mit `+all`
Prüft, ob der SPF-Eintrag auf `+all` (oder ein nacktes `all`) endet und damit ausdrücklich jeden Server als Absender zulässt.
DMARC mit `p=none`
Prüft, ob der DMARC-Eintrag noch auf `p=none` steht und Empfänger damit gefälschte Mails weiterhin zustellen sollen.
Kein DKIM-Schlüssel unter üblichen Selektoren gefunden
Fragt eine Handvoll gängiger DKIM-Selektoren ab und meldet, wenn unter keinem ein Schlüssel liegt — ein Hinweis, keine Feststellung.
TLS-Zertifikat abgelaufen
Liest das Zertifikat des Hosts aus und prüft, ob sein Gültigkeitsdatum überschritten ist.
TLS-Zertifikat läuft in Kürze ab
Liest das Zertifikat des Hosts aus und meldet, wenn es in 14 Tagen oder weniger abläuft.
Selbstsigniertes TLS-Zertifikat
Prüft, ob das ausgelieferte Zertifikat von seinem eigenen Inhaber statt von einer öffentlichen Zertifizierungsstelle beglaubigt ist.
Kein CAA-Eintrag
Prüft, ob die Domain per CAA-Eintrag festlegt, welche Zertifizierungsstellen Zertifikate für sie ausstellen dürfen.
Keine security.txt — keine Meldestelle für Sicherheitslücken
Prüft, ob unter `/.well-known/security.txt` eine Datei nach RFC 9116 mit Kontaktangabe liegt.
security.txt ohne oder mit abgelaufenem Expires
Prüft, ob die vorhandene security.txt die Pflichtzeile `Expires:` trägt und ob das Datum noch in der Zukunft liegt.
package.json öffentlich abrufbar
Prüft, ob unter `/package.json` die Projektdatei mit Name und Abhängigkeitsliste ausgeliefert wird.
API-Beschreibung (OpenAPI/Swagger) öffentlich abrufbar
Prüft die gängigen Pfade (`/openapi.json`, `/swagger.json`, `/api-docs`, `/docs` …) auf eine OpenAPI-/Swagger-Beschreibung oder eine Swagger-UI-/ReDoc-Seite.
Fremde Skripte ohne Subresource Integrity
Findet `<script src>` und `<link rel=stylesheet>` von öffentlichen CDNs (cdnjs, jsDelivr, unpkg, jQuery, Bootstrap …) ohne `integrity`-Attribut.
Datenbank steht offen (Verbund)
Fasst zusammen, was einzeln erklärbar wäre: Zugangsschlüssel im ausgelieferten Code, fehlende oder durchlässige Row Level Security und — für die kritische Stufe — Schreibzugriffe direkt aus dem Browser.
Mehrere Geheimnis-Familien im selben Stand (Verbund)
Feuert, wenn mindestens zwei voneinander unabhängige Geheimnisse (Service-Role-Schlüssel, Datenbank-Verbindung, Zugangsdaten, Anbieter-Schlüssel, Git-Historie) im selben Lauf gefunden wurden.
Phishing-fertig: Mail-Fälschung plus Login (Verbund)
Verbindet eine Domain ohne SPF/DMARC mit einem Anmelde- oder Kontaktformular auf der Seite — die Zutaten einer glaubwürdigen Phishing-Mail im Namen der Domain.
Tabellen ohne Row Level Security
Sammelt alle `create table` und alle `enable row level security` über sämtliche Migrationen und meldet Tabellen, die nie geschützt werden.
RLS-Policy erlaubt allen Zugriff
Findet Policies mit `using (true)` — RLS ist aktiv, wirkt aber nicht.
RLS-Policy prüft nur die Anmeldung, nicht den Eigentümer
Findet Policies mit `auth.role() = 'authenticated'` oder `auth.uid() is not null` ohne Bezug auf den Datensatz-Eigentümer.
RLS-Policy erlaubt beliebiges Schreiben
Findet `with check (true)` — die Lesebedingung kann streng sein, geschrieben werden darf trotzdem alles.
Edge Function ohne JWT-Prüfung
Findet `verify_jwt = false` in `supabase/config.toml` — die Serverfunktion ist ohne Anmeldung aufrufbar.
Firebase-Regeln erlauben allen Zugriff
Findet `allow …: if true` in `.rules`-Dateien — Firestore oder Storage stehen offen.
service_role-Schlüssel im Quellcode
Dekodiert JWTs in Quelldateien und meldet den Rollen-Claim `service_role`; auf dem Syntaxbaum zusätzlich Client-Dateien, die den Schlüssel aus der Umgebung lesen (Kommentare zählen nicht).
Geheimschlüssel im Quellcode
Sucht Muster echter Geheimnisse in Quelldateien (Stripe, AWS, OpenAI, Anthropic, Slack, SendGrid, PEM).
Datenbank-Zugangsdaten im Klartext
Findet Connection-Strings mit eingebettetem Benutzer und Passwort.
.env-Datei versioniert
Erkennt eine `.env` mit gesetzten Werten im Quellstand (nicht `.env.example`).
Supabase genutzt, Schema nicht versioniert
Meldet, wenn Supabase im Code steckt, aber keine Migrationen mit Tabellen und RLS vorliegen — dann ist der Zugriffsschutz aus dem Code nicht verifizierbar.
Geheimnis über öffentliches Env-Präfix exponiert
Findet Variablen mit öffentlichem Bundler-Präfix (`NEXT_PUBLIC_`, `VITE_`, `REACT_APP_`, `PUBLIC_`, `EXPO_PUBLIC_` …), deren Name auf ein Geheimnis hindeutet — solche Werte landen fest im Client-Bundle.
Env-Datei im ausgelieferten Bundle
Erkennt eine `.env` mit gesetzten Werten unter den aus Source Maps rekonstruierten Dateien — der Build hat sie mit ausgeliefert.
Server Action ohne Zugriffsprüfung
Wertet den Körper jeder `"use server"`-Funktion aus, die schreibend auf die Datenbank zugreift, und meldet fehlende Identitätsprüfung — Server Actions sind öffentliche Endpunkte.
Systemprompt im ausgelieferten Code
Prüft, ob die Steueranweisung eines KI-Assistenten im Browser-Code mitgeliefert wird.
Ausgelieferte Bibliothek mit bekannter Schwachstelle
Erkennt Frontend-Bibliotheken samt Version im ausgelieferten Bundle und in rekonstruierten Source Maps (retire.js-Signaturen) und gleicht die Version gegen OSV bzw. die mitgelieferte retire.js-Datenbank ab. Meldet nur bei sicher erkannter Version.
Abhängigkeiten mit bekannter Schwachstelle
Gleicht die Paketversionen des Repos gegen die öffentliche OSV-Datenbank ab und nennt die betroffenen Pakete mit Advisory-ID.
Geheimschlüssel in der Git-Historie
Prüft die hinzugefügten Zeilen der letzten Commits gegen dieselbe Musterliste wie den aktuellen Stand — ein gelöschter Schlüssel bleibt lesbar.
Env-Datei war im Repository und wurde entfernt
Meldet Umgebungsdateien, die in der geprüften Historie auftauchen, im aktuellen Stand aber fehlen — die alten Werte bleiben abrufbar.
Angemeldete Fremde lesen fremde Datensätze
Legt nach Domain-Nachweis ein Wegwerf-Konto an und zählt, wie viele Zeilen dieses fremde Konto in personenbezogenen Tabellen sieht — ohne eine einzige Zeile abzurufen.
Tabelle für jeden Angemeldeten vollständig lesbar
Meldet Tabellen, die anonym verborgen sind, einem frisch angelegten Fremdkonto aber alle Zeilen zeigen — bei Katalogdaten gewollt, sonst derselbe Fehler wie bei personenbezogenen Tabellen.
Mandantentrennung hält im Test
Bestätigt, dass ein frisch angelegtes Konto ohne eigene Daten in den geprüften Tabellen keine Zeilen sah.
Fremdes Konto sieht eure hochgeladenen Dateien
Prüft mit einem Wegwerf-Konto, ob nicht-öffentliche Datei-Ablagen auflistbar sind.
Datei-Ablage gegen fremde Konten abgeschottet
Die positive Gegenaussage: Kein nicht-öffentlicher Bucket gab einem fremden Konto eine Dateiliste.
Fremdes Konto darf in eure Tabellen schreiben
Legt ein Wegwerf-Konto an und prüft je Tabelle, ob es schreiben darf.
Schreibzugriff für fremde Konten abgewiesen
Die positive Gegenaussage: Die geprüften Tabellen wiesen jeden Schreibversuch ab.
Prüfung auf fremde Datensätze nicht durchführbar
Hält fest, dass kein Konto angelegt werden konnte (Registrierung zu oder Bestätigung nötig) — die Mandantentrennung bleibt damit ungeprüft.
Zugriffsprüfung erst nach dem Schreibzugriff
Vergleicht die Position von Auth-Aufruf und Datenbank-Schreibvorgang im selben Funktionskörper und meldet, wenn geprüft wird, nachdem geschrieben wurde.
Auth-Ergebnis wird nie ausgewertet
Meldet Funktionen, die die Identität abfragen, das Ergebnis aber weder prüfen noch an den Schreibvorgang binden — der Aufruf bleibt wirkungslos.
API-Route ohne Zugriffsprüfung
Findet Route Handler mit schreibenden Methoden, in denen keine Authentifizierung vorkommt.
Eingaben ungeprüft in die Datenbank
Verfolgt Request-Bodies, die ohne Schema-Validierung in ein Insert oder Update fließen (Mass Assignment).
Webhook ohne Signaturprüfung
Erkennt Zahlungs-Webhooks, die den Payload verarbeiten, ohne die Signatur zu verifizieren — jeder kann dann Zahlungen vortäuschen.
Ungeprüftes HTML gerendert
Findet `dangerouslySetInnerHTML` mit dynamischem Wert — der klassische XSS-Pfad.
Datenschutz (DSGVO)
Google Fonts zur Laufzeit geladen
Findet Einbindungen von fonts.googleapis.com/gstatic.com, bei denen die IP der Nutzer an Google geht.
US-Tracking ohne sichtbare Einwilligung
Erkennt Analytics- und Pixel-Skripte mit Drittland-Transfer im ausgelieferten Markup.
Pflichtangaben nicht sichtbar
Prüft bei Zielen mit DE-, AT- oder CH-Bezug, ob Impressum und Datenschutzerklärung verlinkt sind.
Datenschutz-Signale unauffällig
Standardisierte Einordnung, wenn von außen keine Drittland-Transfers erkennbar sind.
Tracker feuern vor der Einwilligung
Beobachtet im Browser, welche Third-Party-Hosts schon beim ersten Aufruf kontaktiert werden, bevor irgendetwas zugestimmt wurde — der belegbare Verstoß, den statische Prüfungen nur vermuten können.
Daten an Drittland-Dienste
Listet zur Laufzeit kontaktierte Fremd-Hosts, die typischerweise außerhalb der EU verarbeiten.
Tracker ohne Consent-Oberfläche
Meldet einwilligungspflichtige Skripte, ohne dass im Markup irgendeine Consent-Mechanik erkennbar ist.
Tracking-Cookies ohne Einwilligung gesetzt
Beobachtet im Browser, welche Cookies gesetzt werden, bevor irgendeine Einwilligung erteilt wurde.
Fremd-Cookies ohne Einwilligung gesetzt
Meldet Cookies fremder Domains, die vor jeder Einwilligung gesetzt wurden.
Einwilligung ohne gleichwertiges Ablehnen
Prüft im gerenderten Zustand, ob neben dem Zustimmen auch ein Ablehnen auf derselben Ebene steht.
Impressum: Musterwerte aus der Vorlage
Prüft, ob im Impressum noch Beispielwerte stehen — Muster-Anschrift, Platzhalter-E-Mail, unersetzte Vorlagen-Felder.
Kundenstimme mit erfundenem Gesicht
Findet Portraits aus Zufallsgeneratoren in Abschnitten, die Kundenstimmen oder Referenzen zeigen.
Erzeugte Medien ohne sichtbaren Hinweis
Prüft bei Apps, die Bilder oder Töne erzeugen, ob irgendwo im sichtbaren Text steht, dass Inhalte von einer KI stammen.
Kontaktdaten im ausgelieferten JavaScript
Findet E-Mail-Adressen und Telefonnummern im Klartext in den ausgelieferten JavaScript-Bundles — nicht im HTML, wo das Impressum sie verlangt.
Liste von E-Mail-Adressen öffentlich im Markup
Zählt verschiedene E-Mail-Adressen im ausgelieferten HTML der Startseite und der entdeckten Unterseiten und meldet ab zehn — das sieht nach einer öffentlich gerenderten Mitglieder- oder Kundenliste aus.
CSP-Verstöße werden an einen Drittanbieter gemeldet
Liest `report-uri` und `report-to` aus der Content-Security-Policy (Header oder Meta-Tag) und meldet, wenn die Berichte an einen fremden Host gehen.
Ablehnen wirkt nicht — Tracker laden trotzdem
Klickt im Browser das erkannte „Ablehnen“ des Consent-Banners und beobachtet, ob danach weiterhin Tracking-Dienste kontaktiert oder Tracking-Cookies gesetzt werden — der Differentialscan, der ein vorhandenes Banner erst belastbar macht.
Ablehnen wirkt
Positivbefund des Differentialscans: Nach dem Klick auf „Ablehnen“ wurden keine Tracking-Dienste kontaktiert und keine Tracking-Cookies gesetzt.
Bilder ohne Herkunfts-Kennzeichnung
Prüft bei Apps, die Bilder erzeugen, ob den ausgelieferten Bildern die unsichtbare Angabe „von einer KI erstellt“ noch anhängt.
Dienst nicht in der Datenschutzerklärung genannt
Gleicht die Dienste, die eure App im Browser tatsächlich anspricht, gegen den Text eurer Datenschutzerklärung ab.
KI-Interaktion ohne erkennbaren Hinweis
Findet KI-Endpunkte im Client, ohne dass im sichtbaren Text auf die KI-Interaktion hingewiesen wird.
Tracking-Cookie mit sehr langer Laufzeit
Misst die Laufzeit gesetzter Tracking-Cookies und meldet alles über einem Jahr.
Einwilligung mit vorangekreuzten Kästchen
Findet bereits angekreuzte Auswahlkästchen in der Consent-Oberfläche.
Impressum: Pflichtangaben nicht gefunden
Ruft die Impressumsseite ab und sucht Anschrift, Kontaktmöglichkeit und die Kennung des Rechtsraums (USt-ID/Handelsregister, Firmenbuch/UID, CHE-UID/Handelsregister).
Datenschutzerklärung: Pflichtangaben nicht gefunden
Ruft die Datenschutzerklärung ab und sucht Verantwortlichen, Betroffenenrechte, Beschwerderecht und Speicherdauer.
Formular ohne Datenschutzhinweis
Findet Formulare mit E-Mail-Feld, in deren Umfeld kein Hinweis auf die Datenschutzerklärung steht.
Consent-Theater (Verbund)
Fasst zusammen, wenn ein Banner mit Ablehnen-Möglichkeit vorhanden ist und einwilligungspflichtige Dienste trotzdem laden — vor der Entscheidung oder nach dem Klick auf „Ablehnen“.
Skalierung & Kosten
Abfragen ohne Limit
Findet Datenbank-Abfragen, die ganze Tabellen ohne `limit`/`range` laden — funktioniert bei 10 Datensätzen, kippt bei 10.000.
Sehr großes JavaScript-Bundle
Misst die ausgelieferten Skript-Bytes gegen ein Budget — jedes Megabyte kostet Ladezeit und mobile Abbrüche.
Bilder ohne Optimierung
Zählt Bilder ohne Größenangabe oder moderne Formate — treibt Traffic-Kosten und Layout-Sprünge.
Keine Cache-Strategie
Prüft, ob Antworten Cache-Direktiven tragen — ohne sie zahlt jeder Aufruf den vollen Preis.
Antworten unkomprimiert
Prüft, ob Text-Antworten mit gzip/brotli ausgeliefert werden.
Abfragen in der Schleife (N+1)
Erkennt `await` innerhalb einer Schleife über Datensätze — pro Zeile ein Roundtrip.
Schwerer erster Seitenaufruf
Misst im Browser die tatsächlich übertragenen Bytes des ersten Aufrufs.
Skalierungs-Signale unauffällig
Standardisierte Einordnung, wenn Bundle, Caching und Bilder im Rahmen liegen.
Barrierefreiheit (BFSG)
Keine Sprachauszeichnung
Prüft das `lang`-Attribut am `<html>`-Element — ohne es liest der Screenreader in der falschen Sprache vor.
Bilder ohne Alternativtext
Zählt `<img>`-Elemente ohne `alt`-Attribut im ausgelieferten Markup.
Formularfelder ohne Label
Findet Eingabefelder ohne zugeordnetes Label oder `aria-label` — mit Screenreader nicht bedienbar.
Barrierefreiheits-Verstöße im gerenderten Zustand
Führt axe-core gegen die fertig gerenderte Seite aus und meldet die Verstöße nach Schweregrad — die Prüfung, die statische Analyse nicht leisten kann.
BFSG-Relevanz erkannt
Erfasst Hinweise auf Verkauf oder Dienstleistung an Verbraucher — dann greift das Barrierefreiheitsstärkungsgesetz für den digitalen Auftritt.
Barrierefreiheits-Signale unauffällig
Standardisierte Einordnung, wenn Sprache, Alternativtexte und Labels im Markup vorhanden sind.
Architektur & SEO
Plattform erkannt
Erkennt die verwendete No-Code-/KI-Plattform und gewichtet deren typische Lücken.
Framework-Stack erkannt
Erkennt den Framework-Stack bei framework-nativen Builds (Cursor, Claude Code, klassisch).
Domain-Inhaberschaft nachgewiesen
Bestätigt einen erbrachten Nachweis (DNS-TXT oder Datei) und schaltet die aktiven Prüfungen frei.
Wegwerf-Konto für die Prüfung angelegt
Benennt das Konto, das der Scan für den Nachweis der Mandantentrennung über eure Selbstregistrierung angelegt hat — damit es löschbar bleibt.
Consent-Anbieter erkannt
Benennt die eingebundene Consent-Management-Plattform (Usercentrics, OneTrust, Cookiebot, Borlabs, …) — oder dass nur Googles Consent Mode ohne Banner vorhanden ist.
Dienste und Routen der App erkannt
Liest aus dem ausgelieferten JavaScript, womit die App spricht: eigene Routen, Backend-Dienste (Supabase, Firebase …), KI-Anbieter und weitere fremde Dienste — als Liste mit Methode und Fundstelle.
Testdaten konnten nicht entfernt werden
Benennt Datensätze, die die Schreibprüfung angelegt und nicht wieder gelöscht hat.
Inhalt nur clientseitig gerendert
Erkennt leere Root-Container mit kaum Text im initialen HTML.
Grundlegende Metadaten fehlen
Prüft Seitentitel und Meta-Description im Dokument.
Unveränderter Vorlagen-Titel
Erkennt Generator-Standardtitel wie „Vite + React“ — Hinweis auf ungeprüfte Tool-Defaults.
Kein Canonical-Link
Prüft, ob die Seite eine kanonische URL benennt (Duplicate-Content-Schutz).
Nicht existierende Pfade antworten mit 200
Ruft einen zufälligen Pfad ab: liefert die App dort Inhalt mit Status 200, kann weder Browser noch Suchmaschine Fehler erkennen.
Keine robots.txt und keine Sitemap
Prüft, ob das Ziel Crawling-Hinweise und eine Sitemap ausliefert.
Platzhalter-Texte im Auslieferungsstand
Durchsucht den sichtbaren Text der erreichten Seiten nach Blindtext, Muster-Angaben und unersetzten Vorlagen-Feldern.
Gemischte Ansprache auf einer Seite
Zählt Du-, Ihr- und Sie-Form im sichtbaren Text einer Seite und meldet, wenn zwei davon nebeneinander stehen.
Sehr großes Dokument — Auswertung teilweise
Hält fest, dass das HTML-Dokument die Prüfgrenze überschritten hat und nur bis dorthin ausgewertet wurde. Kein Mangel, sondern eine Angabe zur Abdeckung.
Service Worker erkannt
Erkennt einen registrierten oder unter `/sw.js` bzw. `/service-worker.js` liegenden Service Worker und wertet seinen Quelltext wie ein Bundle aus.
Progressive Web App erkannt
Erkennt ein per `<link rel="manifest">` verlinktes Web-App-Manifest mit Name oder Start-URL.
Entwicklungs-Adresse im ausgelieferten Code
Findet Aufrufe an localhost, 127.0.0.1, private Netzadressen oder Tunnel (ngrok) im ausgelieferten JavaScript — Reste aus der Entwicklung, die bei Nutzern ins Leere laufen.
Code-Qualität
Source Maps öffentlich
Erkennt ausgelieferte Source Maps, aus denen sich der Originalquellcode rekonstruieren lässt.
Debug-Reste im Auslieferungsstand
Findet `console.log`, `debugger` oder TODO-Marker im Produktions-Bundle.
Code-Interna begrenzt sichtbar
Transparenz-Finding: ohne Source Maps oder Repo-Zugang lässt sich Code-Qualität nicht seriös bewerten.
Nicht alle Bundles ausgewertet
Hält fest, dass die Bundle-Auswertung an der Budgetgrenze endete — Funde bleiben gültig, das Fehlen von Funden sagt nichts.
Quellcode aus Source Maps rekonstruiert
Transparenz-Finding: benennt, wie viele Originaldateien aus öffentlichen Source Maps gelesen wurden.
Abdeckung des Deep-Scans
Transparenz-Finding: benennt die Anzahl read-only analysierter Repository-Dateien.
Keine Dateien lesbar
Meldet einen Deep-Scan ohne gelesene Quelldateien — das Ergebnis ist dann nicht aussagekräftig.
Repository nur teilweise gelesen
Meldet, dass die Dateiauswahl an der Budgetgrenze abgeschnitten wurde — Abwesenheits-Regeln schweigen dann, und ein GO ist ausgeschlossen.