CommunityCodierung & Entwicklunggithub.com

atokim4/supabase-rls-audit

Überprüft Supabase Row-Level-Sicherheit (RLS) anhand der Migrationsdateien in einem Repository.

Was ist supabase-rls-audit?

Dieses Skill führt die Datenbankprüfung des vibe-preflight-Scanners aus, indem es SQL-Migrationsdateien analysiert, ohne eine Verbindung zur Datenbank herzustellen. Es erkennt neun häufige Sicherheitsprobleme: Tabellen in public ohne aktiviertes RLS, permissive Policies mit `using (true)` oder `with check (true)`, Tabellen mit RLS aber ohne Policies, Update-Policies die privilegierte Spalten wie `plan` oder `role` betreffen, Views die RLS umgehen, Views über `auth.users`, SECURITY DEFINER Funktionen ohne fixen search_path oder mit anon-Zugriff, sowie öffentliche Storage-Buckets. Das Skill ist nützlich, bevor eine Supabase-App live geht, nach dem Schreiben einer Migration, bei der Überprüfung von Lovable-, Bolt- oder Cursor-Builds, oder wenn der Benutzer nach RLS-Richtlinien fragt. Es unterstützt Claude Code und andere Agenten, die Skills im `.agents/skills/`- oder `.claude/skills/`-Verzeichnis nutzen. Die Ausgabe erfolgt als JSON oder Text, mit Ergebnissen gruppiert nach Regel und Schweregrad, sowie Vorschlägen zur Behebung jedes Problems.

Funktioniert mit✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/atokim4/vibe-preflight/tree/HEAD/skills/supabase-rls-audit

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Supabase RLS-Audit

Dieses Skill führt den Datenbank-Teil des vibe-preflight-Scanners aus (scripts/preflight.mjs neben dieser Datei, Node 20+, keine Abhängigkeiten, kein Netzwerk). Es liest die .sql-Dateien im Projekt (Supabase-Migrationen, schema.sql), spielt Tabellen, Policies, Views, Funktionen, Grants und Storage-Buckets in der richtigen Reihenfolge ab und meldet 9 Probleme. Es stellt keine Verbindung zu einer Datenbank her.

Ausführung

Vom Projektstammverzeichnis:

node ${CLAUDE_SKILL_DIR}/scripts/preflight.mjs . --only database --format json

Claude Code füllt ${CLAUDE_SKILL_DIR} ein. Andere Agenten: Verwende den Ordner dieses Skills, z.B. .agents/skills/supabase-rls-audit oder .claude/skills/supabase-rls-audit.

Exit-Code 1 bedeutet mindestens einen Fehler. Füge --fail-on warning hinzu, um auch bei Warnungen fehlzuschlagen, --explain (Textausgabe) für die Begründung und Behebung jedes Problems. JSON: { summary: { error, warning }, findings: [{ rule, severity, message, file, line }] }.

Wenn das Ergebnis 0 SQL-Dateien anzeigt, existieren die Policies wahrscheinlich nur im Dashboard. Bitte den Benutzer, supabase db pull auszuführen (das schreibt das entfernte Schema in eine Migration) und erneut zu scannen. Melde das Projekt nicht als sauber von einem leeren Scan.

Die Prüfungen

RegelStufeBedeutung
rls-disablederrorEine public-Tabelle erhält nie enable row level security, daher kann jeder mit dem anon-Key sie über die API lesen und schreiben.
rls-permissive-policyerror beim Schreiben, warning beim Lesenusing (true) oder with check (true). Bei Insert/Update/Delete kann jeder Benutzer die Zeilen anderer ändern. Bei Select ist jede Zeile öffentlich.
rls-no-policywarningRLS aktiviert, keine Policies: Die API verweigert alles. Gut für reine Server-Tabellen; eine stille leere Liste, wenn der Browser sie liest.
rls-update-privileged-columnwarningBenutzer können ihre eigene Zeile aktualisieren und sie enthält plan, role, is_admin, credits oder ähnliches. RLS schränkt Zeilen ein, nicht Spalten.
view-bypasses-rlserrorEin View ohne security_invoker = true läuft als sein Besitzer und umgeht RLS auf den darunterliegenden Tabellen.
auth-users-exposederrorEin View in public selektiert aus auth.users.
definer-search-pathwarningEine security definer-Funktion ohne set search_path.
definer-function-anonerror / warningEine security definer-Funktion in public, die anon unter /rest/v1/rpc/<name> aufrufen kann. Error bei explizitem Grant an anon, Warning bei Supabases Standard-Grant.
storage-public-bucketerror / warningEin öffentlicher Bucket. Error, wenn eine Select-Policy auf storage.objects es auch jedem erlaubt, ihn aufzulisten.

Behebung

Schreibe immer eine neue Migration. Bearbeite niemals eine, die bereits auf einer Datenbank ausgeführt wurde.

Fehlende oder zu permissive Policies: Frage, welchen Zugriff die App benötigt, und schränke jede Policy auf eine Rolle und den Besitzer ein.

alter table public.notes enable row level security;
create policy "notes: read own" on public.notes
  for select to authenticated using ((select auth.uid()) = user_id);
create policy "notes: insert own" on public.notes
  for insert to authenticated with check ((select auth.uid()) = user_id);

Privilegierte Spalten: Erlaube Updates nur auf den Spalten, die Benutzer ändern dürfen.

revoke update on public.profiles from authenticated;
grant update (display_name, avatar_url) on public.profiles to authenticated;

Views: alter view public.<name> set (security_invoker = true); (Postgres 15+, alle aktuellen Supabase-Projekte). Ein materialisierter View kann RLS nicht nutzen: Verschiebe ihn aus public oder entziehe das Select-Recht für anon, authenticated. Kopiere bei auth.users die teilbaren Felder mit einem Sign-Up-Trigger in public.profiles.

SECURITY DEFINER-Funktionen: Füge set search_path = '' hinzu und schreibe jeden Namen mit seinem Schema. Schränke dann ein, wer sie aufrufen darf:

revoke execute on function public.admin_set_plan(uuid, text) from public, anon, authenticated;
grant execute on function public.admin_set_plan(uuid, text) to service_role;

Das Entziehen von public allein reicht bei Supabase nicht, da anon einen eigenen Grant auf neue Funktionen hat.

Storage: Mache private Buckets privat, schränke Lesezugriffe auf den Ordner des Besitzers ein ((storage.foldername(name))[1] = (select auth.uid())::text) und serviere signierte URLs. Produktbilder und Logos können öffentlich bleiben.

Ein Befund, der beabsichtigt ist (ein öffentlicher Katalog, eine reine Server-Tabelle), kann mit -- vibe-preflight-ignore <rule-id> in derselben Zeile oder der Zeile darüber unterdrückt werden. Schreibe den Grund in denselben Kommentar.

Berichterstattung

  1. Öffne jede gemeldete Zeile und bestätige sie vor Änderungen am SQL. Der Scanner liest SQL-Text und kann falsch liegen; sage dies, wenn es der Fall ist.
  2. Gruppiere die Zusammenfassung nach Regel. Zuerst die Fehler, dann die Warnungen, die du mit dem Benutzer bestätigt hast.
  3. Führe den Scan nach der Behebung erneut aus und berichte das neue Ergebnis.

Grenzen

  • Nur das, was in .sql-Dateien steht. Dashboard-spezifische Änderungen, andere Schemata und was eine Funktion innerhalb ihres Rumpfes tut, werden nicht geprüft.
  • Ein sauberes Ergebnis bedeutet, dass diese 9 Muster nicht gefunden wurden. Es beweist nicht, dass die Policies den Regeln der App entsprechen. Tests als echter anon- und eingeloggter Benutzer (der Supabase-Client mit dem anon-Key) sind weiterhin empfehlenswert.
  • Für die Browser- und Umgebungsseite (service_role-Key im Client-Code, Geheimnisse in NEXT_PUBLIC_-Variablen, eingecheckte .env) führe den vollständigen Scan ohne --only aus oder verwende das Skill vibe-preflight.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Verwandte Skills