Zum Inhalt springen

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üfen

Wie 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

  1. 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.
  2. 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.
  3. 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.10. Jede inhaltliche Regeländerung erhöht sie, damit ältere Ergebnisse einordenbar bleiben.

Sicherheit

RSC-SEC-001high

Kein durchgängiges HTTPS

Prüft, ob die finale Antwort verschlüsselt ausgeliefert wird oder auf http endet.

RSC-SEC-002medium

HSTS-Header fehlt

Prüft, ob Strict-Transport-Security gesetzt ist und der erste Aufruf damit abgesichert wird.

RSC-SEC-003medium

Keine Content-Security-Policy

Prüft Header und Meta-Tag auf eine Content-Security-Policy als Schutzschicht gegen XSS.

RSC-SEC-004low

MIME-Sniffing nicht unterbunden

Prüft, ob `X-Content-Type-Options: nosniff` das Erraten von Inhaltstypen verhindert.

RSC-SEC-005low

Kein Clickjacking-Schutz

Prüft X-Frame-Options bzw. CSP `frame-ancestors` gegen das Einbetten in fremde Seiten.

RSC-SEC-006info

CORS-Wildcard am öffentlichen Dokument

Erfasst `Access-Control-Allow-Origin: *` am HTML — allein keine Lücke, aber ein Prüf-Signal.

RSC-SEC-007info

Server-Technologie preisgegeben

Erfasst Version-Header wie `X-Powered-By`, die gezielte Exploit-Suche erleichtern.

RSC-SEC-008medium

Cookies ohne Secure/HttpOnly

Prüft gesetzte Cookies auf die Flags Secure und HttpOnly.

RSC-SEC-009info

Supabase-Client-Konfiguration sichtbar

Erfasst Projekt-URL und anon-Key im Bundle — erwartbar, aber Ausgangspunkt der Zugriffsprüfung.

RSC-SEC-010critical

Supabase service_role-Schlüssel im Client

Dekodiert JWTs im Bundle und meldet den Rollen-Claim `service_role`, der RLS vollständig umgeht.

RSC-SEC-011critical

Geheimschlüssel im ausgelieferten Code

Sucht Muster echter Geheimnisse (Stripe, AWS, GitHub, PEM) im HTML und in den Bundles.

RSC-SEC-012info

Firebase-Backend erkannt

Erfasst Firebase-Konfiguration im Client — zulässig, entscheidend sind die Sicherheitsregeln.

RSC-SEC-013critical

.env-Datei öffentlich abrufbar

Ruft bekannte Env-Pfade ab und bestätigt Treffer inhaltlich anhand von KEY=VALUE-Zeilen.

RSC-SEC-014critical

.git-Verzeichnis öffentlich

Bestätigt ein ausgeliefertes `.git` über die Signaturen von `config` und `HEAD`.

RSC-SEC-015medium

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.

RSC-SEC-028critical

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.

RSC-SEC-029medium

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.

RSC-SEC-030critical

Datenbank-Zugangsdaten im Client sichtbar

Findet Connection-Strings mit eingebettetem Benutzer und Passwort im HTML oder in den Bundles.

RSC-SEC-031critical

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.

RSC-SEC-032medium

Datenbank-Funktionen für anonyme Aufrufer freigegeben

Listet die der anon-Rolle zugeteilten RPC-Funktionen aus der Schema-Beschreibung — gelesen, nicht aufgerufen.

RSC-SEC-033medium

Registrierung offen, Konten sofort bestätigt

Liest die anonym abrufbare Auth-Konfiguration: Selbstregistrierung offen und E-Mail-Bestätigung deaktiviert.

RSC-SEC-034high

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`.

RSC-SEC-035medium

Browser schreibt direkt in die Datenbank

Findet Schreibaufrufe (`insert`, `update`, `upsert`, `delete`, Storage-Upload) im ausgelieferten Code bzw. in `use client`-Dateien.

RSC-SEC-036critical

Zugangsdaten fest im Browser-Code verglichen

Findet Vergleiche wie `password === "…"` gegen ein festes Literal im ausgelieferten Code.

RSC-SEC-016medium

Storage-Buckets öffentlich listbar

Prüft, ob Datei-Buckets ihre Objektliste anonym herausgeben.

RSC-SEC-017critical

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.

RSC-SEC-018high

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.

RSC-SEC-019medium

Rollenprüfung im Client-Bundle

Findet Rollenvergleiche wie `role === "admin"` im ausgelieferten JavaScript — im Browser beliebig manipulierbar.

RSC-SEC-020medium

Zugangstoken in localStorage

Beobachtet zur Laufzeit, ob ein JWT-artiger Wert in Web-Storage landet — per XSS auslesbar.

RSC-SEC-021high

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.

RSC-SEC-022critical

Backup- oder Datenbank-Dump öffentlich

Prüft typische Dump-/Backup-Pfade und bestätigt Treffer über SQL- bzw. Archiv-Signaturen.

RSC-SEC-023info

Keine Permissions-Policy

Prüft, ob Kamera, Mikrofon und Standort per Header explizit eingeschränkt werden.

RSC-SEC-024low

Keine Referrer-Policy

Prüft, ob ausgehende Links interne URLs samt Query an Dritte weitergeben.

RSC-SEC-025medium

Unverschlüsselte Inhalte auf HTTPS-Seite

Findet per `http://` eingebundene Skripte, Stylesheets oder Bilder auf einer https-Seite.

RSC-SEC-026medium

Anmeldung ohne erkennbare Sperre

Sendet nach Ownership-Nachweis eine kleine Serie fehlerhafter Anmeldeversuche und prüft, ob überhaupt gebremst wird.

RSC-SEC-027high

Admin-Bereich anonym erreichbar

Ruft entdeckte Verwaltungs-Pfade anonym auf und meldet, wenn Inhalt statt Weiterleitung zur Anmeldung kommt.

RSC-SEC-050high

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.

RSC-SEC-051critical

RLS-Policy erlaubt allen Zugriff

Findet Policies mit `using (true)` — RLS ist aktiv, wirkt aber nicht.

RSC-SEC-066high

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.

RSC-SEC-067critical

RLS-Policy erlaubt beliebiges Schreiben

Findet `with check (true)` — die Lesebedingung kann streng sein, geschrieben werden darf trotzdem alles.

RSC-SEC-068high

Edge Function ohne JWT-Prüfung

Findet `verify_jwt = false` in `supabase/config.toml` — die Serverfunktion ist ohne Anmeldung aufrufbar.

RSC-SEC-069high

Firebase-Regeln erlauben allen Zugriff

Findet `allow …: if true` in `.rules`-Dateien — Firestore oder Storage stehen offen.

RSC-SEC-052high

service_role-Schlüssel im Quellcode

Dekodiert JWTs in Quelldateien und meldet den Rollen-Claim `service_role`.

RSC-SEC-053high

Geheimschlüssel im Quellcode

Sucht Muster echter Geheimnisse in Quelldateien (Stripe, AWS, OpenAI, Anthropic, Slack, SendGrid, PEM).

RSC-SEC-054high

Datenbank-Zugangsdaten im Klartext

Findet Connection-Strings mit eingebettetem Benutzer und Passwort.

RSC-SEC-055high

.env-Datei versioniert

Erkennt eine `.env` mit gesetzten Werten im Quellstand (nicht `.env.example`).

RSC-SEC-056medium

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.

RSC-SEC-057critical

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.

RSC-SEC-063critical

Env-Datei im ausgelieferten Bundle

Erkennt eine `.env` mit gesetzten Werten unter den aus Source Maps rekonstruierten Dateien — der Build hat sie mit ausgeliefert.

RSC-SEC-058high

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.

RSC-SEC-080high

Abhängigkeiten mit bekannter Schwachstelle

Gleicht die Paketversionen des Repos gegen die öffentliche OSV-Datenbank ab und nennt die betroffenen Pakete mit Advisory-ID.

RSC-SEC-081high

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.

RSC-SEC-082medium

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.

RSC-SEC-070critical

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.

RSC-SEC-071medium

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.

RSC-SEC-072info

Mandantentrennung hält im Test

Bestätigt, dass ein frisch angelegtes Konto ohne eigene Daten in den geprüften Tabellen keine Zeilen sah.

RSC-SEC-076critical

Fremdes Konto sieht eure hochgeladenen Dateien

Prüft mit einem Wegwerf-Konto, ob nicht-öffentliche Datei-Ablagen auflistbar sind.

RSC-SEC-077info

Datei-Ablage gegen fremde Konten abgeschottet

Die positive Gegenaussage: Kein nicht-öffentlicher Bucket gab einem fremden Konto eine Dateiliste.

RSC-SEC-074critical

Fremdes Konto darf in eure Tabellen schreiben

Legt ein Wegwerf-Konto an und prüft je Tabelle, ob es schreiben darf.

RSC-SEC-075info

Schreibzugriff für fremde Konten abgewiesen

Die positive Gegenaussage: Die geprüften Tabellen wiesen jeden Schreibversuch ab.

RSC-SEC-073info

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.

RSC-SEC-064high

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.

RSC-SEC-065high

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.

RSC-SEC-059high

API-Route ohne Zugriffsprüfung

Findet Route Handler mit schreibenden Methoden, in denen keine Authentifizierung vorkommt.

RSC-SEC-060medium

Eingaben ungeprüft in die Datenbank

Verfolgt Request-Bodies, die ohne Schema-Validierung in ein Insert oder Update fließen (Mass Assignment).

RSC-SEC-061high

Webhook ohne Signaturprüfung

Erkennt Zahlungs-Webhooks, die den Payload verarbeiten, ohne die Signatur zu verifizieren — jeder kann dann Zahlungen vortäuschen.

RSC-SEC-062high

Ungeprüftes HTML gerendert

Findet `dangerouslySetInnerHTML` mit dynamischem Wert — der klassische XSS-Pfad.

Datenschutz (DSGVO)

RSC-PRV-001medium

Google Fonts zur Laufzeit geladen

Findet Einbindungen von fonts.googleapis.com/gstatic.com, bei denen die IP der Nutzer an Google geht.

RSC-PRV-002medium

US-Tracking ohne sichtbare Einwilligung

Erkennt Analytics- und Pixel-Skripte mit Drittland-Transfer im ausgelieferten Markup.

RSC-PRV-003high

Pflichtangaben nicht sichtbar

Prüft bei deutschsprachigen Zielen, ob Impressum und Datenschutzerklärung verlinkt sind.

RSC-PRV-004info

Datenschutz-Signale unauffällig

Standardisierte Einordnung, wenn von außen keine Drittland-Transfers erkennbar sind.

RSC-PRV-005high

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.

RSC-PRV-006medium

Daten an Drittland-Dienste

Listet zur Laufzeit kontaktierte Fremd-Hosts, die typischerweise außerhalb der EU verarbeiten.

RSC-PRV-007medium

Tracker ohne Consent-Oberfläche

Meldet einwilligungspflichtige Skripte, ohne dass im Markup irgendeine Consent-Mechanik erkennbar ist.

RSC-PRV-008high

Tracking-Cookies ohne Einwilligung gesetzt

Beobachtet im Browser, welche Cookies gesetzt werden, bevor irgendeine Einwilligung erteilt wurde.

RSC-PRV-009medium

Fremd-Cookies ohne Einwilligung gesetzt

Meldet Cookies fremder Domains, die vor jeder Einwilligung gesetzt wurden.

RSC-PRV-010medium

Einwilligung ohne gleichwertiges Ablehnen

Prüft im gerenderten Zustand, ob neben dem Zustimmen auch ein Ablehnen auf derselben Ebene steht.

RSC-PRV-016low

KI-Interaktion ohne erkennbaren Hinweis

Findet KI-Endpunkte im Client, ohne dass im sichtbaren Text auf die KI-Interaktion hingewiesen wird.

RSC-PRV-014low

Tracking-Cookie mit sehr langer Laufzeit

Misst die Laufzeit gesetzter Tracking-Cookies und meldet alles über einem Jahr.

RSC-PRV-015medium

Einwilligung mit vorangekreuzten Kästchen

Findet bereits angekreuzte Auswahlkästchen in der Consent-Oberfläche.

RSC-PRV-011low

Impressum: Pflichtangaben nicht gefunden

Ruft die Impressumsseite ab und sucht Anschrift, Kontaktmöglichkeit und Register- bzw. USt-ID.

RSC-PRV-012low

Datenschutzerklärung: Pflichtangaben nicht gefunden

Ruft die Datenschutzerklärung ab und sucht Verantwortlichen, Betroffenenrechte, Beschwerderecht und Speicherdauer.

RSC-PRV-013low

Formular ohne Datenschutzhinweis

Findet Formulare mit E-Mail-Feld, in deren Umfeld kein Hinweis auf die Datenschutzerklärung steht.

Architektur & SEO

RSC-DET-001info

Plattform erkannt

Erkennt die verwendete No-Code-/KI-Plattform und gewichtet deren typische Lücken.

RSC-DET-002info

Framework-Stack erkannt

Erkennt den Framework-Stack bei framework-nativen Builds (Cursor, Claude Code, klassisch).

RSC-DET-003info

Domain-Inhaberschaft nachgewiesen

Bestätigt einen erbrachten Nachweis (DNS-TXT oder Datei) und schaltet die aktiven Prüfungen frei.

RSC-DET-004info

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.

RSC-DET-005info

Testdaten konnten nicht entfernt werden

Benennt Datensätze, die die Schreibprüfung angelegt und nicht wieder gelöscht hat.

RSC-ARC-001medium

Inhalt nur clientseitig gerendert

Erkennt leere Root-Container mit kaum Text im initialen HTML.

RSC-ARC-002low

Grundlegende Metadaten fehlen

Prüft Seitentitel und Meta-Description im Dokument.

RSC-ARC-003low

Unveränderter Vorlagen-Titel

Erkennt Generator-Standardtitel wie „Vite + React“ — Hinweis auf ungeprüfte Tool-Defaults.

RSC-ARC-004low

Kein Canonical-Link

Prüft, ob die Seite eine kanonische URL benennt (Duplicate-Content-Schutz).

RSC-ARC-005medium

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.

RSC-ARC-006low

Keine robots.txt und keine Sitemap

Prüft, ob das Ziel Crawling-Hinweise und eine Sitemap ausliefert.

RSC-ARC-007info

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.