Ist deine Supabase-App sicher?
Darf Supabase echte Nutzerdaten halten? Ja, denn es ist gebaut, direkt aus dem Browser abgefragt zu werden. Genau deshalb entscheiden zwei Einstellungen alles.

Logos sind Eigentum ihrer jeweiligen Inhaber und dienen nur zur Kennzeichnung der Kompatibilität.
Kurz gesagt
- Supabase darf echte Nutzerdaten halten und ist dafür gebaut, direkt aus dem Browser abgefragt zu werden. Genau deshalb leisten die Regeln auf deinen Tabellen die ganze Arbeit.
- Der öffentliche Schlüssel gehört in deine App. sb_secret_… und service_role umgehen jede Regel, die du geschrieben hast.
- Tabellen aus dem Table Editor bekommen Row Level Security automatisch. Tabellen, die per SQL entstehen, nicht.
Supabase gibt dir eine echte Postgres-Datenbank mit einer API bereits davor, und deshalb kann eine App zwanzig Minuten nach dem Start mit Live-Daten sprechen. Was Leute später überrascht: Dieselbe API ist für jeden erreichbar, von überall, mit Zugangsdaten, die in deiner App abgedruckt sind.
Hier ist der Punkt, den Anleitung um Anleitung falsch darstellt: Das ist kein Mangel, und es zu verstecken ist nicht die Lösung. Supabase ist dafür entworfen, direkt aus einem Browser abgefragt zu werden. Der Schutz sollte immer schon woanders wohnen, und zu wissen, wo, ist der größte Teil dessen, was es über den sicheren Betrieb einer Supabase-App zu wissen gibt.
Warum deine Datenbank mit Absicht im Internet steht
Weil deine App mit ihr aus dem Browser deiner Besucherin spricht und nicht von einem Server, den du betreibst.
Stell es dir als Laden vor. Deine App ist die Ladenfront, jedem Besucher vollständig ausgehändigt. Deine Datenbank ist das Lager, und bei Supabase hat das Lager mit Absicht eine eigene Tür zur Straße, damit deine Ladenfront von dort holen kann, ohne einen Lieferdienst dazwischen. Diese Tür ist das, was dir erspart, ein Backend zu schreiben.
Was bedeutet, dass die Tür öffentlich ist und ihre Adresse in deiner App steht, weil deine App an sie klopfen muss. Es gibt keine Anordnung, in der diese Adresse geheim wäre. Die Frage war also nie „können Fremde meine Datenbank erreichen". Sie können es, so ist es gebaut. Die Frage ist, was sie ihnen aushändigt, wenn sie fragen.
Gehört der Supabase-Schlüssel in meiner App dorthin?
Einer davon ja. Der andere nie, und sie sehen fast identisch aus.
Der öffentliche Schlüssel (sb_publishable_… in neuen Projekten, anon in
älteren) sagt, zu welchem Projekt eine Anfrage gehört. Er trägt selbst keine
Rechte, weshalb Supabases eigene Dokumentation ihn als unbedenklich beschreibt,
um ihn in Webseiten und mobile Apps zu bündeln. Ihn in deiner App zu finden ist
kein Befund.
Der geheime Schlüssel, sb_secret_… oder das ältere service_role, ist das
Gegenteil. Er umgeht deine Regeln vollständig und liest und schreibt jede Zeile
in jeder Tabelle, von überall. Er gehört auf einen Server, in eine Edge Function,
in einen Worker: nirgendwohin, wo ein Browser hinkommt.
Sie liegen auf derselben Dashboard-Seite nebeneinander und haben dieselbe Form. Wurde einer je in Frontend-Code eingefügt, tausche ihn im Dashboard aus, bevor du irgendetwas änderst, denn die Zeile zu löschen schließt die Tür nicht.
Diese Seite ist Settings, dann API Keys, und dort stehen vier Werte statt zwei.
Die Einstellung, die entscheidet, was die Tür aushändigt
Row Level Security: ein Schalter pro Tabelle, der Zeile für Zeile entscheidet, wer was lesen darf. Sie ist der ganze Grund, warum ein öffentlicher Schlüssel unbedenklich ist.
Ist sie aus, gibt dieser Schlüssel jedem, der fragt, die ganze Tabelle. Ist sie an und eine Policy geschrieben, filtert die Datenbank selbst jede Anfrage, einschließlich Anfragen, die nie durch deine App gingen.
Zwei Details entscheiden, ob du sie tatsächlich hast, und keines ist aus deiner App heraus sichtbar:
Wie die Tabelle entstanden ist. Supabase aktiviert Row Level Security automatisch für Tabellen, die im Table Editor des Dashboards gemacht wurden. Tabellen, die per SQL angelegt werden, bekommen sie nicht und müssen bewusst aktiviert werden. Migrationsdateien, Skripte und KI-erzeugte Schemata legen Tabellen alle per SQL an, und ein so gebautes Projekt kann also eine Reihe ungeschützter Tabellen haben, die genau wie die geschützten aussehen.
Was die Policy sagt. Aktiviert heißt zu, bis eine Policy sie öffnet. Eine Policy, die alle durchlässt, öffnet sie ganz, während das Dashboard die Tabelle weiterhin mit aktivierter Row Level Security meldet, der Zustand, der geschützt aussieht und es nicht ist.
Storage ist noch einmal getrennt. Ein öffentlicher Bucket ist für jeden mit deiner Projektadresse auflistbar und herunterladbar, was auch immer deine Tabellenregeln sagen.
So prüfst du dein eigenes Supabase-Projekt in etwa zehn Minuten
Authentication → Policies. Lies die ganze Liste. Jede Tabelle, die Row Level Security als deaktiviert zeigt, ist für jeden lesbar. Bei den Tabellen, die sie als aktiviert zeigen, öffne die Policy und lies, was sie tatsächlich erlaubt.
Settings → API. Bestätige, dass der Schlüssel, den deine App ausliefert, der
öffentliche ist. War je ein geheimer Schlüssel im Frontend-Code, tausche ihn hier
zuerst aus.
Zeigt dein Dashboard Schlüssel, die mit sb_publishable_ und sb_secret_
beginnen statt mit anon und service_role, ist das
das neuere Format, und dieselbe Regel entscheidet,
welcher der beiden in deine App gehört.
Storage → Buckets. Prüfe, welche öffentlich sind, und ob das für die Dateien darin so gemeint war.
Und dann schau von außen. Alles oben ist das, was dein Dashboard als konfiguriert meldet. Was eine anonyme Anfrage tatsächlich zurückbekommt, ist eine andere Frage, und die beantwortet unser kostenloser Scan: Er fragt so, wie ein Fremder fragen würde, ohne eine einzige deiner Zeilen zu lesen, und gibt dir in etwa 20 Sekunden eine Note: prüfen, was deine App preisgibt.
Was zu tun ist
- Deine Supabase-API ist mit Absicht öffentlich. Der Schutz sind die Regeln auf deinen Tabellen, nie die Geheimhaltung der Adresse.
- Der öffentliche Schlüssel gehört in deine App.
sb_secret_…undservice_rolenie, und ein durchgesickerter ignoriert jede Regel, die du geschrieben hast. - Tabellen aus dem Table Editor bekommen Row Level Security automatisch. Tabellen, die per SQL entstehen, nicht.
- Aktiviert ist nicht eingeschränkt. Lies die Policy, nicht nur den Schalter.
- Storage-Buckets haben eigene Einstellungen, also sagen dichte Tabellen nichts über deine Dateien.
Öffne Authentication → Policies und geh die Liste einmal durch. Die als deaktiviert markierten Tabellen sind die, mit denen man anfängt, und wenn du die ganze Fläche lieber als Liste durchgehst, ist die Sicherheits-Checkliste in 10 Minuten die Kurzfassung. Was du auch findest: Zu wissen, dass du die Daten zurückspielen kannst, zählt genauso viel wie sie abzuschließen, und das hängt ganz davon ab, was du sicherst.
Wenn es nicht davon abhängen soll, dass du daran denkst: So funktionieren automatische Supabase-Backups.
Was bei Supabase tatsächlich schiefgehen kann
Nichts davon bedeutet, dass du etwas falsch gemacht hast: Es sind die üblichen Lücken, wenn man schnell unterwegs ist. Das ist einen Blick wert:
Row Level Security (RLS) ausgeschaltet
RLS ist Supabases Regel dafür, wer jede Zeile einer Tabelle lesen oder ändern darf. Mit dem öffentlichen „anon“-Schlüssel (der in deiner App liegen soll) kann jeder deine Datenbank direkt abfragen. RLS ist das, was sie davon abhält, Zeilen zu sehen, die nicht ihnen gehören. Ist es aus, kann eine Tabelle für jeden vollständig lesbar oder sogar änderbar sein. Das ist die wichtigste Supabase-Einstellung, und Reeve prüft sie, indem es Zeilen zählt, nie indem es sie liest.
Ein geleakter service_role-Schlüssel
Supabase gibt dir zwei Schlüssel. Der „anon“-Schlüssel ist von Haus aus öffentlich und im Browser sicher. Der „service_role“-Schlüssel umgeht alle deine Sicherheitsregeln und darf nur auf einem Server leben. Landet er je im Frontend-Code deiner App, kann jemand alles mit deinen Daten anstellen. Reeve dekodiert die gefundenen Schlüssel und sagt dir genau, welcher offengelegt ist: Der sichere „anon“ bekommt ein grünes Häkchen, „service_role“ ist ein roter Alarm.
Öffentliche Speicher-Buckets
Von Leuten hochgeladene Dateien leben in Supabase-Storage-„Buckets“. Ein auf öffentlich gesetzter Bucket bedeutet, dass jeder auflisten und herunterladen kann, was drin ist, sodass private Uploads für alle sichtbar werden können. Reeve prüft, ob deine Buckets auflistbar sind; es lädt nie die Dateien von jemandem herunter.
Deine API offen für jede Website (CORS)
Supabase gibt deiner Datenbank eine Webadresse (über PostgREST). Kombiniert mit einer zu freizügigen Freigabe-Einstellung könnte eine andere Website deine Daten aus dem Browser eines Besuchers aufrufen. Reeve prüft, ob deine Endpunkte Fremden und anderen Seiten antworten, ohne sie je zu nutzen, um etwas zu ändern.
Tabellen und Endpunkte ohne Regeln offengelegt
Jede Tabelle, die du anlegst, ist über Supabases API erreichbar; das ist so gewollt, und RLS soll sie bewachen. Aber eine in Eile hinzugefügte neue Tabelle, bevor ihre Regeln gesetzt sind, kann kurzzeitig (oder dauerhaft) offen sein. Reeve prüft, was tatsächlich von außen erreichbar ist.
Schlüssel oder Konfiguration in der deployten App gelassen
Über Supabases eigene Schlüssel hinaus tragen Apps oft andere Einstellungen und Geheimnisse in ihrem Frontend-Code oder einer offengelegten .env. Reeve liest den geladenen Code deiner App und prüft auf erreichbare Konfigurationsdateien, dann sagt es dir, welche Werte sicher öffentlich sein können und welche nicht.
Was Reeve ist, und was nicht
Reeve ist eine kostenlose, nur-lesende Prüfung von außen, wie ein Inspektor, der die Türen probiert, ohne einzutreten. Sie ist schnell und fängt die häufigen, folgenreichen Fehler ab. Sie ist kein vollständiges Sicherheitsaudit, und eine saubere Note ist keine Garantie. Sie bedeutet, dass die offensichtlichen Türen zu sind. Alles, was Reeve tut, ist passiv: Es zählt Zeilen, statt sie zu lesen, und lädt nie deine Dateien herunter.
Supabase gibt dir echte Sicherheitswerkzeuge (einen Security Advisor und einen Datenbank-Linter, die RLS- und Offenlegungsprobleme direkt im Dashboard melden), und die sind wirklich empfehlenswert. Was Reeve ergänzt: Die meisten, die auf Supabase bauen, leben in ihrem App-Baukasten, nicht im SQL-Editor, und der Advisor spricht Entwickler. Reeve prüft deine ganze App von außen, so, wie ein Angreifer an deine Daten käme, und erklärt in verständlichen Worten, was es findet. Und wenn du sie lieber nicht selbst im Blick behalten möchtest, können wir das.
Willst du es erledigt, nicht nur geprüft?
Reeve Care behält deine App im Blick, sichert deine Daten und hilft dir, Dinge zu reparieren, wenn sie kaputtgehen, damit du weiterbauen kannst, statt dir Sorgen zu machen.
Mehr über Reeve Care erfahrenFAQ
Was ist Supabase-RLS und brauche ich es wirklich?
RLS (Row Level Security) entscheidet, wer jede Zeile in deinen Tabellen sehen oder ändern darf. Weil deine App einen öffentlichen „anon“-Schlüssel ausliefert, der die Datenbank direkt abfragen kann, ist RLS das, was die Daten eines Nutzers davor bewahrt, für alle sichtbar zu sein. Ja: Für jede Tabelle mit echten Daten brauchst du es an. Reeve prüft, ob es an ist, ohne deine Daten zu lesen.
Ist der Supabase-anon-Schlüssel sicher offenzulegen?
Ja. Der „anon“-Schlüssel ist dafür gemacht, in deinem Frontend zu leben, und für sich allein tut er nur, was deine RLS-Regeln erlauben. Der Schlüssel, der nie offengelegt werden darf, ist der „service_role“-Schlüssel, der alle Regeln ignoriert. Reeve dekodiert die Schlüssel in deiner App und sagt dir, welcher welcher ist.
Was passiert, wenn mein service_role-Schlüssel leakt?
Der service_role-Schlüssel umgeht jede Sicherheitsregel, sodass jeder, der ihn hat, all deine Daten lesen, ändern oder löschen kann. Ist er in deinem Frontend-Code, behandle ihn als kompromittiert: rotiere ihn im Supabase-Dashboard und verschiebe ihn auf einen Server. Reeve markiert einen offengelegten service_role-Schlüssel als kritisches Problem.
Kann Reeve mein Supabase ohne mein Datenbank-Passwort prüfen?
Ja. Reeve nutzt nur, was deine App ohnehin öffentlich offenlegt: denselben anon-Schlüssel und dieselben Endpunkte, die der Browser jedes Besuchers nutzt. Es braucht nie dein Datenbank-Passwort, loggt sich nie als Admin ein und liest oder lädt nie deine Zeilen oder Dateien herunter.
Warum lässt Supabase einen Browser überhaupt mit meiner Datenbank sprechen?
Weil das das Produkt ist. Supabase stellt eine API vor Postgres, damit deine App Daten abfragen kann, ohne dass du ein Backend schreibst und betreibst, und genau das macht das Bauen so schnell. Die Sicherheit entsteht nicht dadurch, diese API zu verstecken; verstecken lässt sie sich nicht. Sie entsteht dadurch, dass Postgres sich weigert, Zeilen zurückzugeben, auf die der Besucher keinen Anspruch hat.
Macht es eine Tabelle privat, wenn ich Row Level Security einschalte?
Es macht sie zu, bis du eine Policy schreibst, und das ist der sichere Ausgangspunkt. Aber eine Policy, die alle durchlässt, öffnet sie wieder, während das Dashboard die Tabelle weiterhin mit aktivierter Row Level Security anzeigt. Aktiviert und eingeschränkt sind zwei verschiedene Zustände, und nur einer davon ist auf einen Blick sichtbar.
Welche Tabellen sind am ehesten ungeschützt?
Die, die per SQL entstanden sind statt durch Klicken im Table Editor: Migrationsdateien, Skripte und Schemata, die eine KI für dich geschrieben hat. Der Table Editor schaltet Row Level Security automatisch ein. SQL nicht, und hinterher weist nichts auf den Unterschied hin.
Ist mein Supabase-Speicher von Row Level Security abgedeckt?
Storage hat eigene, getrennte Einstellungen, also sagt eine dichte Datenbank nichts über deine Dateien. Ein als öffentlich markierter Bucket kann von jedem aufgelistet und heruntergeladen werden, der deine Projektadresse kennt, ob deine App je auf den Inhalt verlinkt oder nicht.