[{"data":1,"prerenderedAt":800},["ShallowReactive",2],{"blog-de-enable-rls-on-every-supabase-table":3,"blog-index-de":561},{"id":4,"title":5,"body":6,"category":517,"cover":518,"coverAlt":519,"description":520,"draft":521,"extension":522,"faq":523,"image":539,"keywords":540,"meta":549,"navigation":550,"ogTitle":551,"path":552,"published":553,"seo":554,"stem":555,"tldr":556,"updated":553,"__hash__":560},"blog_de\u002Fblog\u002Fenable-rls-on-every-supabase-table.md","Row Level Security für jede Supabase-Tabelle aktivieren und prüfen",{"type":7,"value":8,"toc":505},"minimark",[9,13,21,26,29,32,39,45,48,52,55,58,69,80,86,89,95,98,114,118,121,127,133,159,165,171,174,180,186,193,275,287,291,294,297,302,305,308,314,318,321,324,327,333,342,345,349,352,358,365,370,391,404,411,415,418,421,433,436,439,451,455,492],[10,11,12],"p",{},"Man hat dir gesagt, du sollst Row Level Security anschalten, oder dein\nKI-Baukasten hat es beiläufig erwähnt, während er etwas anderes repariert hat.\nIn deinem Supabase-Projekt liegen irgendwo zwischen vier und vierzig Tabellen,\nund du weißt nicht, welche davon abgedeckt sind.",[10,14,15,16,20],{},"Die Anleitung, die du überall findest, ist eine Zeile SQL pro Tabelle, und so\nweit stimmt sie auch. Wovor fast jede Anleitung haltmacht, ist der Schritt\ndanach. ",[17,18,19],"strong",{},"Eine Policy, die existiert, ist keine Policy, die funktioniert",", und\nnichts in deinem Dashboard zeigt dir den Unterschied. Row Level Security in\nSupabase zu aktivieren sind also drei Arbeiten statt einer: den Schalter über\nalle Tabellen legen, die zwei oder drei Policies schreiben, die deine App wieder\nzusammensetzen, und dann deine eigene Datenbank das fragen, was ein Fremder sie\nfragen würde.",[22,23,25],"h2",{"id":24},"was-macht-row-level-security-eigentlich","Was macht Row Level Security eigentlich?",[10,27,28],{},"Es sorgt dafür, dass Postgres deine Regeln prüft, bevor es eine Zeile\nherausgibt. Ist der Schalter aus, gibt es keine Regeln zu prüfen, und deshalb\nlautet die Antwort auf jede Anfrage: alles.",[10,30,31],{},"Stell dir einen Bibliothekar vor, der holt, was immer du verlangst. Row Level\nSecurity ist die Anweisung, vor dem Beladen des Wagens einen Zettel über dich zu\nlesen. Der Zettel ist deine Policy, und darauf kann stehen, dass diese Person\ndie Bücher mitnehmen darf, die sie selbst geschrieben hat, oder dass jeder alles\nmitnehmen darf. Gilt die Anweisung und ist noch kein Zettel geschrieben, kommt\nder Bibliothekar mit einem leeren Wagen zurück und sagt nicht, warum.",[10,33,34,35,38],{},"Genau daran stolpern die Leute, und es entscheidet darüber, wie ein Test später\naussieht. ",[17,36,37],{},"Row Level Security filtert Zeilen. Sie weist keine Anfragen ab.","\nEine Tabelle, die du nicht lesen darfst, antwortet mit einer leeren Liste und\neinem Erfolgscode, nicht mit einem Fehler oder einer Anmeldeaufforderung. Deiner\nApp wird nie gesagt, dass sie abgewiesen wurde. Sie bekommt nichts und zeigt\neinen leeren Bildschirm.",[40,41],"diagram",{"alt":42,"caption":43,"src":44},"Dieselbe Anfrage dreimal gezeichnet. Mit ausgeschaltetem Sicherheitsschalter kommen vier hell gezeichnete Zeilen zurück. Mit angeschaltetem Schalter und ohne Policy kommt ein leerer gestrichelter Platz zurück. Mit angeschaltetem Schalter und einer Besitzer-Policy kommt eine hell gezeichnete Zeile zurück. Alle drei Rückgaben sind mit 200 gekennzeichnet.","Eine Anfrage, drei Einstellungen und jedes Mal derselbe Erfolgscode. Row Level Security ändert, was zurückkommt, nie ob die Anfrage geklappt hat.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fsame-request-three-answers-1600x780.png",[10,46,47],{},"Den Schalter über ein Projekt zu legen, in dem noch keine Policies stehen,\nsperrt also keine Fremden aus deinen Daten aus. Es sperrt alle aus, deine eigene\nApp eingeschlossen, bis du sagst, wer was sehen darf.",[22,49,51],{"id":50},"wie-aktiviere-ich-rls-in-jeder-supabase-tabelle-auf-einmal","Wie aktiviere ich RLS in jeder Supabase-Tabelle auf einmal?",[10,53,54],{},"Eine Schleife, einmal im SQL Editor ausgeführt. Sie geht jede Tabelle in deinem\npublic-Schema durch und legt den Schalter überall dort um, wo er aus ist.",[10,56,57],{},"Sieh dir zuerst an, wo du stehst. Das hier listet deine Tabellen auf und sagt zu\njeder, ob sie ihn gerade hat:",[59,60,65],"pre",{"className":61,"code":63,"language":64},[62],"language-text","select tablename, rowsecurity\nfrom pg_tables\nwhere schemaname = 'public'\norder by tablename;\n","text",[66,67,63],"code",{"__ignoreMap":68},"",[10,70,71,72,75,76,79],{},"Jede Zeile, in der ",[66,73,74],{},"rowsecurity"," auf ",[66,77,78],{},"false"," steht, ist eine Tabelle, die ihren\nInhalt an jeden herausgibt, der den veröffentlichbaren Schlüssel hat, den deine\nApp ausliefert. Ist die Liste kurz, mach sie einzeln und sieh zu, was kaputt\ngeht:",[59,81,84],{"className":82,"code":83,"language":64},[62],"alter table public.orders enable row level security;\n",[66,85,83],{"__ignoreMap":68},[10,87,88],{},"Ist sie nicht kurz, erledigt das hier alles:",[59,90,93],{"className":91,"code":92,"language":64},[62],"do $$\ndeclare t record;\nbegin\n  for t in\n    select tablename from pg_tables where schemaname = 'public'\n  loop\n    execute format(\n      'alter table public.%I enable row level security', t.tablename\n    );\n  end loop;\nend $$;\n",[66,94,92],{"__ignoreMap":68},[10,96,97],{},"Führ das aus, und deine App wird leer. Supabase schreibt es in der eigenen\nDokumentation klar hin: Über die API mit einem veröffentlichbaren Schlüssel sind\ndie Daten nicht mehr erreichbar, bis Policies definiert sind. Das ist der\nSchalter bei der Arbeit, und deshalb ist der nächste Abschnitt der, den du offen\nhaben solltest, bevor du auf Ausführen drückst.",[99,100,102],"callout",{"type":101},"warn",[10,103,104,107,108,113],{},[17,105,106],{},"Die Tabellen, die dein Baukasten gemacht hat, waren die offenen."," Eine\nTabelle, die du dir im Supabase Table Editor zusammenklickst, bekommt Row Level\nSecurity angeschaltet. Eine Tabelle, die per SQL entsteht, nicht, und per SQL\nlegen Lovable, Bolt, Cursor und v0 Tabellen für dich an. Die Tabellen, bei deren\nEntstehen du nie zugesehen hast, sind genau die, für die diese Schleife da ist,\nund\n",[109,110,112],"a",{"href":111},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","was die Warnung \"RLS disabled in public\" erwischt und was nicht","\nerklärt, warum dein Dashboard dazu geschwiegen haben kann.",[22,115,117],{"id":116},"die-drei-policies-die-du-wirklich-brauchst","Die drei Policies, die du wirklich brauchst",[10,119,120],{},"Fast jede Tabelle in einer App wie deiner hat eine von drei Formen: Zeilen, die\neiner Person gehören, Zeilen, die jeder lesen darf, und Zeilen, die deine App\nfür einen Besucher schreibt. Hier ist jede davon, fertig zum Einfügen und\nUmbenennen.",[10,122,123,126],{},[17,124,125],{},"Zeilen, die einer Person gehören."," Bestellungen, Nachrichten, gemerkte\nArtikel, alles mit einem Besitzer.",[59,128,131],{"className":129,"code":130,"language":64},[62],"create policy \"read own orders\"\non public.orders for select\nto authenticated\nusing ( (select auth.uid()) = user_id );\n",[66,132,130],{"__ignoreMap":68},[10,134,135,138,139,142,143,146,147,150,151,154,155,158],{},[66,136,137],{},"auth.uid()"," ist die id dessen, der bei dieser Anfrage angemeldet ist.\n",[66,140,141],{},"user_id"," ist die Spalte deiner Tabelle, in der der Besitzer steht, also prüf\nden Namen, bevor du das ausführst: Baukästen schreiben auch ",[66,144,145],{},"owner_id",",\n",[66,148,149],{},"profile_id"," und ",[66,152,153],{},"created_by",". Die Zeile ",[66,156,157],{},"to authenticated"," bedeutet, dass die\nPolicy für einen abgemeldeten Besucher gar nicht erst betrachtet wird, und genau\ndas hält die Tabelle vor der Öffentlichkeit zu.",[10,160,161,164],{},[17,162,163],{},"Zeilen, die jeder lesen darf."," Ein Produktkatalog, veröffentlichte Artikel,\neine Karte mit Veranstaltungsorten.",[59,166,169],{"className":167,"code":168,"language":64},[62],"create policy \"anyone may read products\"\non public.products for select\nto anon, authenticated\nusing ( true );\n",[66,170,168],{"__ignoreMap":68},[10,172,173],{},"Schreib die hier bewusst oder gar nicht, denn es ist auch die Policy, zu der ein\nKI-Baukasten greift, sobald du ihn bittest, einen leeren Bildschirm zu\nreparieren. Die Frage, die vorher zu klären ist: Könnte diese Tabelle genau so,\nwie sie dasteht, eine Seite auf deiner Website sein, ohne dass etwas\nherausgenommen wird? Ein Nein heißt, sie will stattdessen die Besitzer-Policy\nvon oben.",[10,175,176,179],{},[17,177,178],{},"Zeilen, die deine App schreibt."," Lesen und Schreiben sind in Postgres\ngetrennte Rechte, also braucht eine Tabelle, in die deine App speichert, eine\nzweite Policy, und die prüft die Zeile auf dem Weg hinein statt auf dem Weg\nhinaus.",[59,181,184],{"className":182,"code":183,"language":64},[62],"create policy \"insert own orders\"\non public.orders for insert\nto authenticated\nwith check ( (select auth.uid()) = user_id );\n",[66,185,183],{"__ignoreMap":68},[10,187,188,189,192],{},"Welche Klausel wohin gehört, ist der Teil, an dem es hakt, und die Zeile\n",[66,190,191],{},"update"," trägt eine Anforderung, an der nichts naheliegend ist:",[194,195,196,212],"table",{},[197,198,199],"thead",{},[200,201,202,206,209],"tr",{},[203,204,205],"th",{},"Operation",[203,207,208],{},"Klausel",[203,210,211],{},"Braucht außerdem",[213,214,215,230,244,262],"tbody",{},[200,216,217,223,228],{},[218,219,220],"td",{},[66,221,222],{},"select",[218,224,225],{},[66,226,227],{},"using",[218,229],{},[200,231,232,237,242],{},[218,233,234],{},[66,235,236],{},"insert",[218,238,239],{},[66,240,241],{},"with check",[218,243],{},[200,245,246,250,256],{},[218,247,248],{},[66,249,191],{},[218,251,252,150,254],{},[66,253,227],{},[66,255,241],{},[218,257,258,259,261],{},"eine ",[66,260,222],{},"-Policy auf derselben Tabelle",[200,263,264,269,273],{},[218,265,266],{},[66,267,268],{},"delete",[218,270,271],{},[66,272,227],{},[218,274],{},[10,276,277,278,281,282,286],{},"Supabases Dokumentation ist bei der letzten deutlich: Ohne passende\nselect-Policy funktioniert ein update nicht wie erwartet. Und wenn dich die\nMeldung ",[66,279,280],{},"new row violates row-level security policy"," überhaupt erst hierher\ngeführt hat, dann ist der Abstand zwischen diesen beiden Klauseln\n",[109,283,285],{"href":284},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","der ganze Fehler",".",[22,288,290],{"id":289},"warum-jedes-beispiel-select-authuid-statt-authuid-schreibt","Warum jedes Beispiel (select auth.uid()) statt auth.uid() schreibt",[10,292,293],{},"Weil die Klammern Postgres den Wert einmal für die ganze Abfrage ausrechnen\nlassen statt einmal für jede Zeile, die es ansieht.",[10,295,296],{},"Die eingepackte Fassung wird zu dem, was Postgres einen initPlan nennt: einmal\nausgeführt und danach für den Rest der Anweisung wiederverwendet. Ohne die\nKlammern wird die Funktion bei Zeile eins wieder aufgerufen, bei Zeile zwei, bei\nZeile drei, und so weiter durch eine Tabelle, in der hunderttausend davon liegen\nkönnen. Supabases eigener Performance Advisor meldet die Fassung ohne Klammern\nunter einer Regel namens Auth RLS Initialization Plan, und sie gehört zu den\nEinträgen, die dort am häufigsten stehen.",[40,298],{"alt":299,"caption":300,"src":301},"Zwei Panels über denselben acht Tabellenzeilen. Im linken Panel steht neben jeder Zeile ein Funktionszeichen mit einer eigenen Verbindung, acht insgesamt. Im rechten Panel fächert ein einziges Funktionszeichen oben zu allen acht Zeilen auf einmal auf.","Die Klammern sind der ganze Unterschied. Links läuft die Funktion einmal pro Zeile, rechts läuft sie einmal und die Antwort wird wiederverwendet.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fonce-per-query-1600x620.png",[10,303,304],{},"Ein Vorbehalt, und der kommt von Supabase selbst: Das funktioniert, weil die\nAntwort von Zeile zu Zeile gleich bleibt. Eine Funktion, deren Ergebnis\ntatsächlich von der Zeile vor ihr abhängt, lässt sich nicht aus der Schleife\nziehen, die also ohne Klammern lassen.",[10,306,307],{},"Wenn du schon dabei bist, leg einen Index auf die Spalte, nach der deine\nPolicies filtern. Die Policy wird zu einer Bedingung bei jedem Lesen dieser\nTabelle, und bei einer Tabelle mit vielen Zeilen macht sich eine Spalte ohne\nIndex in deinen Antwortzeiten bemerkbar:",[59,309,312],{"className":310,"code":311,"language":64},[62],"create index orders_user_id_idx on public.orders (user_id);\n",[66,313,311],{"__ignoreMap":68},[22,315,317],{"id":316},"eine-policy-testen-ohne-ein-falsches-konto-anzulegen","Eine Policy testen, ohne ein falsches Konto anzulegen",[10,319,320],{},"Der Supabase SQL Editor kann eine Abfrage so ausführen, als hätte ein bestimmter\nBesucher sie geschickt, und damit ist der anonyme Fall komplett abgedeckt.",[10,322,323],{},"Der Editor hat ein Bedienelement für die Rolle, unter der eine Abfrage laufen\nsoll. Stell es auf die anonyme Rolle und führ dann ein gewöhnliches select gegen\ndie Tabelle aus, die du gerade geändert hast. Was zurückkommt, ist das, was ein\nabgemeldeter Fremder bekommt. Für einen angemeldeten Besucher nimm die id eines\nNutzers, den du schon hast, statt einen neuen anzulegen; jede Zeile in deiner\neigenen Tabelle reicht zum Testen.",[10,325,326],{},"Wenn du lieber tippst als klickst, dasselbe in SQL:",[59,328,331],{"className":329,"code":330,"language":64},[62],"begin;\nset local role anon;\nselect * from public.orders;\nrollback;\n",[66,332,330],{"__ignoreMap":68},[10,334,335,150,338,341],{},[66,336,337],{},"begin",[66,339,340],{},"rollback"," stehen da, damit der Rollenwechsel nur für diesen Block\ngilt und nicht länger, was zählt, wenn du in einem Rutsch mehrere Tabellen\ndurchgehst.",[10,343,344],{},"Was dir das sagt, ist, was deine Policies innerhalb der Datenbank tun. Was es\ndir nicht sagen kann, ist, was dein Projekt ins Internet hinausgibt, denn die\nAnfrage, die deine Besucher tatsächlich stellen, beginnt nicht im SQL Editor.\nSie beginnt in einem Browser, trägt einen veröffentlichbaren Schlüssel und kommt\nüber die öffentliche Adresse deines Projekts an.",[22,346,348],{"id":347},"wie-teste-ich-supabase-rls-von-außerhalb-meiner-app","Wie teste ich Supabase RLS von außerhalb meiner App?",[10,350,351],{},"Schick die Anfrage, die ein Fremder schicken würde. Du brauchst zwei Werte, und\nbeide stecken schon in dem Code, den deine Seite jedem Besucher ausliefert: die\nURL deines Projekts und deinen veröffentlichbaren Schlüssel.",[59,353,356],{"className":354,"code":355,"language":64},[62],"curl \"https:\u002F\u002FYOUR-PROJECT.supabase.co\u002Frest\u002Fv1\u002Forders?select=*&limit=1\" \\\n  -H \"apikey: YOUR_PUBLISHABLE_KEY\" \\\n  -H \"Authorization: Bearer YOUR_PUBLISHABLE_KEY\"\n",[66,357,355],{"__ignoreMap":68},[10,359,360,361,364],{},"Setz einen Tabellennamen nach dem anderen ein und lies, was zurückkommt. Eine\nleere Liste, ",[66,362,363],{},"[]",", heißt, die Policy hat für einen abgemeldeten Besucher\ngehalten. Eine Zeile heißt, dass jeder mit einem Schlüssel, den deine App\nausliefert, diese Tabelle lesen kann. Ein Fehler, der den Schlüssel selbst\nerwähnt, heißt, du hast den falschen Wert kopiert, und das schließt man besser\naus, bevor man irgendetwas folgert.",[40,366],{"alt":367,"caption":368,"src":369},"Eine gestrichelte Grenze um eine Datenbanktabelle. Innerhalb steht eine Lupe neben der Tabelle, mit einem kurzen Pfeil. Außerhalb schickt eine Person einen Pfeil, der einen Schlüssel durch eine Lücke in der Grenze trägt, mit dem Pfad Schrägstrich rest Schrägstrich v1 neben der Lücke, und erreicht dieselbe Tabelle.","Der Test im Editor verlässt das Gebäude nie. Die Anfrage von außen kommt über dieselbe öffentliche Adresse an, die deine Besucher benutzen, und trägt denselben Schlüssel, den deine App ausliefert.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Ftwo-tests-one-table-1600x640.png",[10,371,372,373,376,377,380,381,385,386,390],{},"Bei einem neueren Supabase-Projekt beginnt dieser Schlüssel mit\n",[66,374,375],{},"sb_publishable_",", bei einem älteren ist es der ",[66,378,379],{},"anon","-Schlüssel. Beide sind so\nsicher zu benutzen und sicher in deiner App, das ist ihr Zweck;\n",[109,382,384],{"href":383},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","welche API-Schlüssel in ein Frontend gehören","\nbehandelt das Paar, das dort nicht hingehört, und\n",[109,387,389],{"href":388},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","wo du sie im Dashboard findest"," sind die\nvier Werte auf dieser Einstellungsseite.",[10,392,393,394,398,399,403],{},"Das ist der Test, der der Wirklichkeit entspricht, und ihn in großem Maßstab zu\nfahren ist der Grund, warum wir wissen, wie verbreitet die Lücke ist. Zwischen\ndem 12. und 14. August 2026 haben wir neun externe Prüfungen über 30.998\nlaufende Apps aus Lovable, Base44, Replit, v0 und Bolt fahren lassen. Von den\n3.680 Supabase-Apps, bei denen die Prüfung durchlief, haben 2.096 auf eine\nanonyme Anfrage Zeilen aus mindestens einer Tabelle zurückgegeben. Das sind\n57 %, und zwar als Anteil an den Apps, die uns eine klare Antwort gegeben haben,\nnicht an allem, was wir gescannt haben. Der\n",[109,395,397],{"href":396},"\u002Fresearch\u002Fvibe-coded-app-security-2026","vollständige Datensatz ist veröffentlicht",",\nund ",[109,400,402],{"href":401},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","worauf sich diese 57 % beziehen","\ngeht die Zählung durch.",[10,405,406,407,286],{},"Von Hand ist das bei vier Tabellen in Ordnung und bei vierzig mühsam. Unser\nkostenloser Scan schickt diese Anfrage für dich, findet heraus, welche Tabellen\nes gibt, ohne dass du sie nennst, und sagt dir, welche geantwortet haben, neben\nacht weiteren Prüfungen, die er von außen macht. Er liest deine Live-Seite so,\nwie jeder Besucher es kann, dauert etwa 20 Sekunden und braucht kein Konto:\n",[109,408,410],{"href":409},"\u002Fsecurity-scanner","App scannen",[22,412,414],{"id":413},"bevor-du-policies-an-einer-live-tabelle-umschreibst","Bevor du Policies an einer Live-Tabelle umschreibst",[10,416,417],{},"Nimm zuerst eine Kopie deiner Datenbank. Du bist dabei, Rechte über jede Tabelle\nzu ändern, die du hast, mit denselben Werkzeugen, die das Problem erzeugt haben.",[10,419,420],{},"Zwei verschiedene Risiken lohnt es sich zu trennen, denn nur eines davon\nbetrifft die Arbeit von heute. War eine Tabelle für jeden les- und schreibbar,\ndann ändert es nichts an dem, was schon passiert ist, sie jetzt zuzuziehen, und\ndiese Variante zeigt sich meist als Support-Nachricht über Daten, die sich von\nselbst geändert haben. Das andere Risiko ist die Migration selbst. Eine Policy,\ndie gelöscht und leicht falsch wieder angelegt wird, ist ein ganz gewöhnlicher\nDienstag, und der Weg zurück ist eine Kopie davon, wie es vor einer Stunde\naussah.",[10,422,423,424,428,429,286],{},"Auf einem bezahlten Supabase-Plan wartet die Kopie von gestern Nacht in der\nKonsole. Auf dem kostenlosen Plan gibt es gar nichts, worauf man zurückfallen\nkönnte, weil\n",[109,425,427],{"href":426},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Supabase im kostenlosen Tarif keine automatischen Backups macht",".\nWenn das auf dich zutrifft,\n",[109,430,432],{"href":431},"\u002Fblog\u002Fback-up-supabase-free-tier","nimm eines, bevor du anfängst",[10,434,435],{},"Reeve Care ist die Fassung davon, an die du nicht denken musst. Deine\nSupabase-Datenbank wird nach Zeitplan kopiert, außerhalb deines Supabase-Kontos\naufbewahrt, verschlüsselt und zurückgelesen, um zu bestätigen, dass sie sich\nwiederherstellen lässt, bevor sich das Datum in deinem Dashboard bewegt.\nHochgeladene Dateien reisen mit, sobald du einen Storage-Schlüssel verbindest,\nund dieser Schlüssel wird getrennt abgefragt, weil Supabase für Dateien keinen\nNur-Lese-Schlüssel ausgibt: Der, der deine Uploads kopiert, kann auch schreiben,\nder, der deine Datenbank kopiert, nicht. Ihn zu verbinden ist freiwillig, und\ndeine Datenbank wird so oder so gesichert. Backups gibt es nur für Supabase, und\nwenn deine Daten woanders liegen, sagen wir das, statt dir ein Abo für eine\nleere Kiste zu verkaufen.",[10,437,438],{},"Das Wiederherstellen ist der Teil, auf den es an einem Tag wie diesem ankommt.\nCare kopiert den aktuellen Stand deiner Datenbank, bevor es die Fassung\neinspielt, die du ausgewählt hast, das Drücken des Knopfes hat also selbst ein\nRückgängig.",[10,440,441,442,446,447,286],{},"Die andere Hälfte ist die Prüfung, die du gerade von Hand gemacht hast. Eine\nPolicy, die sich bei irgendeiner späteren Migration lockert, findet niemand\ndurch Hinsehen, also fährt Care dieselbe anonyme Anfrage nach Zeitplan erneut\nund sagt dir, wenn eine Tabelle zu antworten beginnt, die letzte Woche still\nwar. Uptime-Überwachung und ein Monatsbericht liegen im selben Abo. Nichts davon\nschreibt deine Policies für dich, und kein Backup macht eine offene Tabelle zu.\nWas sich ändert, ist, was eine schiefgegangene Migration dich kostet.\n",[109,443,445],{"href":444},"\u002Fsupabase-backups","Was Reeve bei Supabase sichert, wie oft, und was eine Wiederherstellung tut","\ngeht den ganzen Kreis durch, und die Tarife stehen auf der\n",[109,448,450],{"href":449},"\u002Fpricing","Preisseite",[22,452,454],{"id":453},"die-reihenfolge-in-der-du-arbeitest","Die Reihenfolge, in der du arbeitest",[456,457,458],"key-takeaways",{},[459,460,461,469,472,479,489],"ul",{},[462,463,464,465,468],"li",{},"Lass dir mit ",[66,466,467],{},"select tablename, rowsecurity from pg_tables where schemaname = 'public'"," deine Tabellen anzeigen und sieh, wie viele offen sind, bevor du etwas änderst.",[462,470,471],{},"Nimm ein Backup und schalte dann Row Level Security in jeder Tabelle im public-Schema an. Rechne damit, dass deine App leer wird; das ist der Schalter bei der Arbeit.",[462,473,474,475,478],{},"Gib jeder Tabelle eine der drei Policies. Besitz ist der Normalfall; ",[66,476,477],{},"USING (true)"," ist eine Entscheidung, die du Tabelle für Tabelle triffst, und kein Weg, die Bildschirme zurückzubekommen.",[462,480,481,482,485,486,488],{},"Schreib ",[66,483,484],{},"(select auth.uid())"," statt ",[66,487,137],{}," und leg einen Index auf die Spalte, nach der deine Policies filtern.",[462,490,491],{},"Prüf jede Tabelle von außen ohne Anmeldung. Eine leere Liste ist bestanden. Eine Zeile ist eine Tabelle, die jeder lesen kann, was auch immer dein Dashboard dazu sagt.",[10,493,494,495,499,500,504],{},"Fang mit der Tabelle an, die dir als öffentliche Seite am peinlichsten wäre, und\narbeite dich von dort nach unten. Die\n",[109,496,498],{"href":497},"\u002Fchecklist","10-Minuten-Sicherheitscheckliste"," deckt das zusammen mit dem Rest\nab, was in einer frisch gestarteten App zu bestätigen ist, und der\n",[109,501,503],{"href":502},"\u002Fis-your-supabase-app-safe","Supabase-Sicherheitsleitfaden"," geht durch, was\nsonst noch offen zu bleiben pflegt.",{"title":68,"searchDepth":506,"depth":506,"links":507},3,[508,510,511,512,513,514,515,516],{"id":24,"depth":509,"text":25},2,{"id":50,"depth":509,"text":51},{"id":116,"depth":509,"text":117},{"id":289,"depth":509,"text":290},{"id":316,"depth":509,"text":317},{"id":347,"depth":509,"text":348},{"id":413,"depth":509,"text":414},{"id":453,"depth":509,"text":454},"Sicherheitsgrundlagen","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcover-1200x630.png","Eine Liste von Datenbanktabellen in einem Panel, neben jeder ein Sicherheitsschalter, und die meisten davon stehen noch auf aus.","Row Level Security in Supabase ohne Policy sperrt eine Tabelle komplett. Eine Policy ohne den Schalter bringt gar nichts. Hier ist das SQL, und der Test.",false,"md",[524,527,530,533,536],{"q":525,"a":526},"Was passiert, wenn ich RLS anschalte und keine Policy schreibe?","Die Tabelle hört auf zu antworten, auch für deine eigene App. Ist der Schalter an, prüft Postgres deine Policies, bevor es eine Zeile herausgibt, und ohne Policies gibt es nichts, was ja sagen könnte, also kommen Anfragen leer zurück. Supabase schreibt das direkt hin: Über die API mit einem veröffentlichbaren Schlüssel sind die Daten nicht mehr erreichbar, bis Policies definiert sind. Es wird nichts gelöscht und nichts geht kaputt. Schreib eine Policy für die Zeilen, die deine App zeigen soll, und die Bildschirme kommen zurück.",{"q":528,"a":529},"Macht Row Level Security meine Abfragen langsamer?","Das kann sein, und die beiden Abhilfen sind klein. Schreib `(select auth.uid())` in die Policy-Bedingung, mit den Klammern, damit Postgres den Wert einmal für die ganze Abfrage ausrechnet und ihn danach für jede Zeile wiederverwendet. Supabase meldet die Fassung ohne Klammern im eigenen Performance Advisor, unter einer Regel namens Auth RLS Initialization Plan. Leg dann einen Index auf die Spalte, nach der die Policy filtert, meist `user_id`. Bei einer Tabelle mit ein paar tausend Zeilen wirst du so oder so kaum etwas merken. Bei einer großen zählt beides.",{"q":531,"a":532},"Brauche ich RLS, wenn in meiner Tabelle keine persönlichen Daten stehen?","Angeschaltet haben willst du es trotzdem, und die Policy darf die freizügige sein. Eine Tabelle mit ausgeschalteter Row Level Security kann jeder lesen, der den veröffentlichbaren Schlüssel hat, den deine App ausliefert, und das ist für einen Produktkatalog in Ordnung und für alles deutlich weniger in Ordnung, was du nicht als Seite veröffentlichen würdest. Sie anzuschalten und eine Lese-Policy mit `USING (true)` zu schreiben gibt dir denselben öffentlichen Zugang mit Absicht, und die Tabelle liest sich beim nächsten Durchgehen der Liste als entschieden statt als vergessen.",{"q":534,"a":535},"Warum funktioniert mein Realtime-Abo nicht mehr, seit ich RLS angeschaltet habe?","Weil Realtime dieselben Policies prüft, bevor es eine Änderung an einen Abonnenten schickt. Eine Tabelle mit angeschalteter Row Level Security und ohne select-Policy für diesen Besucher liefert einer Abfrage keine Zeilen und einem Abo keine Änderungen, aus genau demselben Grund. Füg die select-Policy hinzu, die dieser Abonnent braucht, und der Strom läuft weiter. Wenn du Realtime Broadcast oder Presence statt Datenbankänderungen nutzt, werden die getrennt autorisiert, über Policies auf der Tabelle `realtime.messages`.",{"q":537,"a":538},"Wie teste ich eine Policy, ohne einen falschen Nutzer anzulegen?","Auf zwei Wegen, und keiner davon braucht ein neues Konto. Der Supabase SQL Editor kann eine Abfrage so ausführen, als hätte eine bestimmte Rolle sie geschickt, und damit ist der anonyme Fall komplett abgedeckt: Was zurückkommt, ist das, was ein Fremder bekommt. Für den angemeldeten Fall brauchst du eine Nutzer-id als Platzhalter, und jede Zeile, die schon in deiner Tabelle steht, tut es. Der zweite Weg ist eine Anfrage von außen mit deinem veröffentlichbaren Schlüssel, und die prüft den ganzen Pfad statt nur die Policy.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",[541,542,543,544,545,546,547,548],"row level security supabase aktivieren","supabase rls aktivieren","row level security policies supabase","supabase rls policy beispiel","supabase rls select auth.uid","supabase rls testen","supabase rls best practices","auth.uid() policy",{},true,"Row Level Security für jede Supabase-Tabelle aktivieren","\u002Fblog\u002Fenable-rls-on-every-supabase-table","2026-09-10",{"title":5,"description":520},"blog\u002Fenable-rls-on-every-supabase-table",[557,558,559],"Row Level Security in Supabase ohne Policy sperrt eine Tabelle komplett, und eine Policy zu schreiben, ohne den Schalter anzumachen, bringt gar nichts. Jede Tabelle braucht beides.","Drei Policy-Formen decken fast alles ab, was ein KI-Baukasten anlegt: Zeilen, die einer Person gehören, Zeilen, die jeder lesen darf, und Zeilen, die deine App für einen Besucher schreibt.","Prüf danach von außerhalb deiner App ohne Anmeldung, denn das ist die Anfrage, die ein Fremder stellt, und nur sie sagt dir, was deine Policies tun statt was sie behaupten.","XvhCgxzAsvPE877QpfI3NsiK7EXpfJdPHOR5fxSU0lY",[562,569,575,581,587,593,599,605,611,617,623,629,635,641,642,647,653,659,665,671,677,683,689,695,701,706,712,717,722,728,734,740,746,752,758,763,768,774,779,785,790,796],{"path":563,"title":564,"description":565,"published":566,"category":567,"image":568,"draft":521},"\u002Fblog\u002Fsupabase-backup-auth-users","Warum in deinem Supabase-Dump keine Nutzer stehen","Führe supabase db dump allein aus und du bekommst die Form deiner Datenbank und keine einzige Zeile, und das auth-Schema mit deinen Nutzern fehlt ganz.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":570,"title":571,"description":572,"published":573,"category":517,"image":574,"draft":521},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domain abgelaufen, Website offline: was jetzt passiert","Deine Domain ist abgelaufen und deine Website ist offline. Welche Frist jetzt läuft, warum das Zertifikat das kleinere Problem ist, und wie du beides prüfst.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":576,"title":577,"description":578,"published":579,"category":517,"image":580,"draft":521},"\u002Fblog\u002Fis-lovable-safe","Ist Lovable sicher? Was 18.554 echte Lovable-Apps zeigten","Ist Lovable sicher? Wir haben 18.554 laufende Lovable-Apps mit neun Checks geprüft. Die Plattform war die sauberste von fünf. Die Funde saßen in den Apps.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":582,"title":583,"description":584,"published":585,"category":517,"image":586,"draft":521},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Die Sicherheits-Checkliste für Vibe-Coding, in neun Prüfungen","Eine Sicherheits-Checkliste für Vibe-Coding mit neun Punkten, die jeder von außen an deiner Live-App nachprüfen kann, jeder mit einem Test in einer Zeile.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":588,"title":589,"description":590,"published":591,"category":517,"image":592,"draft":521},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Ein geheimer Stripe-Schlüssel im Frontend kann Geld bewegen","Ein geheimer Stripe-Schlüssel im Frontend kann erstatten, abbuchen und jeden Kundendatensatz lesen, den du hast. Dein pk_live_-Schlüssel gehört dorthin.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":594,"title":595,"description":596,"published":597,"category":517,"image":598,"draft":521},"\u002Fblog\u002Fvite-and-next-public-env-vars","Vite-Env-Variablen offengelegt: der Präfix heißt veröffentlichen","Vite-Env-Variablen offengelegt: Deine App hat getan, was der Präfix verlangt. VITE_ und NEXT_PUBLIC_ heißen veröffentlichen, und die KI kannte den Preis nie.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":600,"title":601,"description":602,"published":603,"category":517,"image":604,"draft":521},"\u002Fblog\u002Fbase44-source-maps","Base44-Sicherheit: was ein Scan meldet und was du ändern kannst","Base44-Sicherheit auf 5.438 gescannten Apps: Drei Befunde auf fast jeder gehören der Plattform, die Source Map ist das Base44-Badge, und deine Liste ist kurz.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":606,"title":607,"description":608,"published":609,"category":517,"image":610,"draft":521},"\u002Fblog\u002Fis-cursor-ai-safe","Ist Cursor AI sicher? Editor, Code und die App, die du veröffentlichst","Ist Cursor AI sicher? Drei Fragen in einer Suche: was Cursor behält, was sein Code falsch macht und ob deine veröffentlichte App offen steht.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":612,"title":613,"description":614,"published":615,"category":517,"image":616,"draft":521},"\u002Fblog\u002Fis-replit-safe","Ist Replit sicher? Was wir in 3.042 Replit-Apps gefunden haben","Ist Replit sicher? Wir haben 3.042 laufende Replit-Apps mit neun externen Checks geprüft. Die Funde saßen in der veröffentlichten App, nicht im Hosting.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":618,"title":619,"description":620,"published":621,"category":567,"image":622,"draft":521},"\u002Fblog\u002Fsupabase-storage-backup","Supabase Storage Backup: deine Datenbankkopie hat keine Dateien","Ein Supabase Storage Backup ist eine eigene Aufgabe. Datenbank-Backups enthalten die Liste deiner Dateien und keine davon, also bleibt jeder Upload kaputt.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":624,"title":625,"description":626,"published":627,"category":567,"image":628,"draft":521},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Supabase Point-in-Time Recovery: Kosten und Grenzen","Supabase Point-in-Time Recovery spult deine Datenbank auf jede Sekunde der letzten Woche zurück. $100 im Monat zusätzlich zu Pro, und nur die Datenbank.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":630,"title":631,"description":632,"published":633,"category":567,"image":634,"draft":521},"\u002Fblog\u002Fsupabase-project-paused-recover","Supabase-Projekt pausiert? Deine Daten sind noch da","Supabase hat dein Projekt nach einer Woche ohne Aktivität pausiert. Gelöscht ist nichts, Wiederherstellen steht neben dem Namen, und du hast ein Jahr.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":636,"title":637,"description":638,"published":639,"category":517,"image":640,"draft":521},"\u002Fblog\u002Fsafest-ai-app-builder","Welcher KI-App-Builder ist am sichersten? 30.998 Apps im Test","Welcher KI-App-Builder ist am sichersten? Wir haben 30.998 aktive Apps von Lovable, Base44, Replit, v0 und Bolt gescannt. Der Builder entscheidet das nicht.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":552,"title":5,"description":520,"published":553,"category":517,"image":539,"draft":521},{"path":111,"title":643,"description":644,"published":645,"category":517,"image":646,"draft":521},"Supabase \"RLS disabled in public\": was die Warnung übersieht","Supabase meldet \"RLS disabled in public\" als Fehler. Zur Lese-Policy, die deine Tabelle genauso offen lässt, sagt der Advisor gar nichts.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":648,"title":649,"description":650,"published":651,"category":517,"image":652,"draft":521},"\u002Fblog\u002Frotate-supabase-service-role-key","Geleakten Supabase-service_role-Schlüssel richtig tauschen","Supabase sagt: erst das Leck schließen. Andere Anleitungen: sofort tauschen. Was richtig ist, hängt davon ab, wohin dein service_role-Schlüssel gelangt ist.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":654,"title":655,"description":656,"published":657,"category":517,"image":658,"draft":521},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Vibe-Coding-Security-Scanner im Vergleich, unserer eingeschlossen","Der beste Vibe-Coding-Security-Scanner hängt an drei Fragen, die keine Funktionsliste beantwortet. Zehn Tools im Vergleich, mit Preisen und unseren Lücken.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":660,"title":661,"description":662,"published":663,"category":517,"image":664,"draft":521},"\u002Fblog\u002Fsupabase-security-checker","Supabase Security Checker: die fünf Prüfungen selbst machen","Ein Supabase Security Checker liest deine veröffentlichte App statt deiner Projekteinstellungen. Hier sind die fünf Prüfungen und wie du jede selbst ausführst.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":666,"title":667,"description":668,"published":669,"category":517,"image":670,"draft":521},"\u002Fblog\u002Fvibe-coding-security-scanner","Vibe-Coding-Security-Scanner: was ein URL-Scan übersieht","Ein Vibe-Coding-Security-Scanner liest deine laufende App von außen. Was das abdeckt, die vier Dinge, die er nicht sehen kann, und wie du das Ergebnis liest.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":672,"title":673,"description":674,"published":675,"category":517,"image":676,"draft":521},"\u002Fblog\u002Fmissing-security-headers","Fehlende Sicherheitsheader: wann sie wirklich zählen","Fehlende Sicherheitsheader ist unser häufigster Befund. Wogegen sie schützen, und wann sie die unwichtigste Zeile in deinem Bericht sind.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":678,"title":679,"description":680,"published":681,"category":517,"image":682,"draft":521},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Dein OpenAI-API-Schlüssel liegt im Frontend. Tausch ihn aus.","Ein OpenAI-API-Schlüssel im Frontend lässt sich an keine Domain binden. Tausch ihn heute, leg den Aufruf hinter deinen Server und begrenze das Budget.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":684,"title":685,"description":686,"published":687,"category":517,"image":688,"draft":521},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","API-Schlüssel im Frontend: was 30.998 Apps wirklich ausliefern","Ein API-Schlüssel im Frontend ist meistens ein Google-Maps-Schlüssel. Wir haben 30.998 aktive Vibe-Coding-Apps gescannt und gezählt, was wirklich austritt.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":690,"title":691,"description":692,"published":693,"category":567,"image":694,"draft":521},"\u002Fblog\u002Fsupabase-backup-tools-compared","Supabase-Backup-Tools im Vergleich, unseres eingeschlossen","Vier Arten von Supabase-Backup-Tool, was jedes wirklich kopiert und wann eine kostenlose GitHub Action jeden Anbieter schlägt, uns eingeschlossen.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":696,"title":697,"description":698,"published":699,"category":517,"image":700,"draft":521},"\u002Fblog\u002Freplit-secrets-explained","Secrets in Replit nutzen, und was trotzdem veröffentlicht wird","Secrets in Replit nutzen: anlegen, auslesen und die zwei Gründe beheben, warum undefined zurückkommt. Dazu die Schlüssel, die das Werkzeug nicht schützt.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":431,"title":702,"description":703,"published":704,"category":567,"image":705,"draft":521},"Supabase Gratis-Tarif: Backup ohne Terminal selbst machen","Im Supabase Gratis-Tarif gibt es keine Backups, die Kopie musst du selbst machen. Wie das im Dashboard geht und was der CSV-Weg auslässt.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":707,"title":708,"description":709,"published":710,"category":517,"image":711,"draft":521},"\u002Fblog\u002Fis-supabase-secure","Ist Supabase sicher? Ja. Dein Projekt ist eine eigene Frage","Ist Supabase sicher? Die Plattform ist auditiert, verschlüsselt und pentestet. Supabase schreibt selbst auf, wo das aufhört und deine Einstellungen anfangen.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":388,"title":713,"description":714,"published":715,"category":517,"image":716,"draft":521},"Wo du deine Supabase API-Keys findest: anon, service_role, URL","Projekt-URL, anon-Schlüssel und service_role-Schlüssel liegen auf einer Seite im Dashboard. Wo sie ist, und welcher der vier Werte in deine App gehört.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":284,"title":718,"description":719,"published":720,"category":517,"image":721,"draft":521},"New row violates row-level security policy in Supabase: was jetzt?","\"New row violates row-level security policy\" heißt, Supabase hat einen Schreibvorgang abgelehnt. Die schnelle Lösung öffnet die Tabelle wieder für alle.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":723,"title":724,"description":725,"published":726,"category":517,"image":727,"draft":521},"\u002Fblog\u002Fcors-wildcard-security-risk","Ist eine CORS-Wildcard ein Sicherheitsrisiko? Meist nicht.","Ist eine CORS-Wildcard ein Sicherheitsrisiko? Meist ist sie die Voreinstellung deines Builders und gibt nichts preis, was dein Server nicht ohnehin herausgab.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":729,"title":730,"description":731,"published":732,"category":567,"image":733,"draft":521},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Supabase Branching ist kein Backup. Es geht nur vorwärts.","Warum Supabase Branching kein Backup ist: Ein Branch startet ohne deine Daten, und ein Merge bringt nur das Schema. Wofür es gut ist und was stattdessen hilft.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":735,"title":736,"description":737,"published":738,"category":567,"image":739,"draft":521},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Supabase-Backup wiederherstellen, und was danach kaputt ist","Wie du ein Supabase-Backup aus dem Dashboard oder aus einer Dump-Datei wiederherstellst, was ersetzt wird und warum die App danach kaputt sein kann.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":741,"title":742,"description":743,"published":744,"category":517,"image":745,"draft":521},"\u002Fblog\u002Fsupabase-storage-bucket-public","Dein Supabase-Storage-Bucket ist öffentlich. Ist das ein Problem?","Ein öffentlicher Supabase-Storage-Bucket heißt: Wer die URL einer Datei hat, kann sie öffnen. Er heißt nicht, dass jemand den Inhalt auflisten darf.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":747,"title":748,"description":749,"published":750,"category":517,"image":751,"draft":521},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Ist ein Google-API-Schlüssel im Frontend ein Problem?","Ein Google-API-Schlüssel im Frontend ist der Fund unseres Scanners Nummer eins, und meistens unbedenklich. Eine kostenlose Einstellung entscheidet darüber.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":753,"title":754,"description":755,"published":756,"category":567,"image":757,"draft":521},"\u002Fblog\u002Fai-agent-deleted-my-database","Ein KI-Agent hat meine Supabase-Daten gelöscht. Was hole ich zurück?","Ein KI-Agent hat Daten aus deiner Datenbank gelöscht. Was du zurückholst, stand schon vorher fest, und die nächsten Minuten entscheiden über den Rest.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":401,"title":759,"description":760,"published":761,"category":517,"image":762,"draft":521},"Kann jeder deine Supabase-Datenbank lesen? 3.680 Apps im Test","Kann jeder deine Supabase-Datenbank ohne Login lesen? Wir haben 30.998 aktive Apps aus KI-Buildern gescannt und gemessen, wie oft die Antwort ja lautet.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":764,"title":765,"description":766,"published":761,"category":517,"image":767,"draft":521},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source-Maps öffentlich: deine App veröffentlicht ihren Quellcode","Eine öffentliche Source-Map lässt jeden den Originalcode deiner App lesen, Kommentare inklusive. Der 30-Sekunden-Check, und was wirklich zählt.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":769,"title":770,"description":771,"published":772,"category":517,"image":773,"draft":521},"\u002Fblog\u002Fsupabase-new-api-keys","Supabases neue API-Schlüssel: welcher gehört in deine App?","Supabase hat anon und service_role durch öffentliche und geheime Schlüssel ersetzt. Welcher gehört in deine App, und welcher nie?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":426,"title":775,"description":776,"published":777,"category":567,"image":778,"draft":521},"Sichert Supabase meine Datenbank? Das hängt von deinem Tarif ab.","Sichert Supabase deine Datenbank? Auf bezahlten Tarifen täglich, im Gratis-Tarif gar nicht. So findest du heraus, was du hast und was es nicht abdeckt.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":780,"title":781,"description":782,"published":783,"category":517,"image":784,"draft":521},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security ist an. Die Tabelle ist trotzdem offen.","Supabase Row Level Security anzuschalten schützt keine Tabelle. Erst deine Policies tun das, und die, die deine App repariert hat, lässt oft alle herein.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":786,"title":787,"description":788,"published":783,"category":567,"image":789,"draft":521},"\u002Fblog\u002Fversion-history-is-not-a-backup","Der Versionsverlauf ist kein Backup. Er holt keine Tabelle zurück.","Lovable und Bolt führen einen Versionsverlauf für deinen Code. Deine Datenbank ist ein eigener Dienst, und ein Rücksprung holt deine Daten nicht zurück.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":567,"image":795,"draft":521},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Drei Wege, eine Supabase-Datenbank zu sichern, und was fehlt","Das Dashboard, pg_dump und ein verwalteter Dienst. Was jeder Weg wirklich sichert, was er stillschweigend auslässt und welcher den Kontoverlust übersteht.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":383,"title":797,"description":798,"published":794,"category":517,"image":799,"draft":521},"Welche API-Schlüssel im Frontend sicher sind, und welche nicht","Dein Supabase-anon-Schlüssel darf öffentlich sein. Der service_role-Schlüssel nicht. Er ignoriert jede Regel, die du setzt. So erkennst du den Unterschied.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1790150951364]