[{"data":1,"prerenderedAt":925},["ShallowReactive",2],{"blog-de-infinite-recursion-in-policy-for-relation":3,"blog-index-de":571},{"id":4,"title":5,"body":6,"category":528,"cover":529,"coverAlt":530,"description":531,"draft":532,"extension":533,"faq":534,"image":549,"keywords":550,"meta":559,"navigation":560,"ogTitle":561,"path":562,"published":563,"seo":564,"stem":565,"tldr":566,"updated":563,"__hash__":570},"blog_de\u002Fblog\u002Finfinite-recursion-in-policy-for-relation.md","\"Infinite recursion detected in policy\" ohne RLS abzuschalten",{"type":7,"value":8,"toc":515},"minimark",[9,13,24,32,37,40,43,60,63,67,70,78,94,100,103,107,113,119,122,126,135,141,144,147,200,211,220,224,230,233,238,241,244,296,299,302,310,318,322,325,335,338,356,372,376,379,396,399,403,409,418,436,447,464,468,507],[10,11,12],"p",{},"Du hast Row Level Security angeschaltet, eine Regel geschrieben, damit Admins\njedes Profil sehen und alle anderen nur ihr eigenes, und jetzt lädt kein\neinziger Bildschirm in deiner App mehr. Jeder Lesezugriff kommt mit derselben\nZeile zurück:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","infinite recursion detected in policy for relation \"profiles\"\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26,27,31],{},"Die meisten Antworten, die du findest, sagen dasselbe, und es ist das Falsche:\n",[28,29,30],"strong",{},"schalte Row Level Security auf dieser Tabelle ab, bis du es herausgefunden\nhast."," Der Fehler hört tatsächlich auf. Er hört auf, weil die Tabelle jetzt\nfür jeden lesbar ist, der deine Seite besucht.",[33,34,36],"h2",{"id":35},"was-infinite-recursion-detected-in-policy-for-relation-bedeutet","Was \"infinite recursion detected in policy for relation\" bedeutet",[10,38,39],{},"Eine Regel auf einer Tabelle musste genau diese Tabelle lesen, bevor sie\nantworten konnte.",[10,41,42],{},"Stell dir einen Türsteher vor, der jeden Besucher gegen eine Gästeliste prüft,\nund die Gästeliste liegt in dem Raum, den er bewacht. Um die Liste zu lesen,\nmuss er hinein. Um hineinzugehen, muss er die Liste prüfen. Es gibt keinen\nersten Schritt, also steht er im Flur und niemand kommt irgendwohin.",[10,44,45,46,49,50,52,53,55,56,59],{},"Genau das ist deiner Datenbank passiert. Sie wurde nach ein paar Zeilen aus\n",[21,47,48],{},"profiles"," gefragt, ging zur Regel auf ",[21,51,48],{},", um herauszufinden, welche du\nsehen darfst, und die Regel schickte sie nach ",[21,54,48],{},". Postgres merkt, dass\nes im Kreis läuft, gibt auf und meldet den Fehler mit dem Code ",[21,57,58],{},"42P17"," daran.\nSupabase reicht ihn unverändert an deine App weiter, deshalb liest er sich wie\nMaschinerie.",[10,61,62],{},"Die Abfrage scheitert für alle, für die die Regel gilt, also kommt das\nüblicherweise als eine ganze App an, die auf einmal leer bleibt, statt als ein\neinzelner kaputter Bildschirm.",[33,64,66],{"id":65},"der-kreis-gezeichnet","Der Kreis, gezeichnet",[10,68,69],{},"Die Regel, die das auslöst, ist die, die fast jeder zuerst schreibt, weil sie\ngenau das sagt, was du meinst:",[14,71,76],{"className":72,"code":74,"language":75,"meta":23},[73],"language-sql","-- Falsch: das liest profiles, um zu entscheiden, wer profiles lesen darf.\ncreate policy \"admins read every profile\" on profiles for select\nto authenticated\nusing (\n  exists (\n    select 1 from profiles\n    where id = (select auth.uid()) and role = 'admin'\n  )\n);\n","sql",[21,77,74],{"__ignoreMap":23},[10,79,80,81,84,85,87,88,90,91,93],{},"Das ",[21,82,83],{},"exists (select 1 from profiles …)"," ist das ganze Problem. ",[21,86,48],{}," zu\nlesen heißt, die Regel auf ",[21,89,48],{}," anzuwenden, und die führt ",[21,92,83],{}," erneut aus.",[95,96],"diagram",{"alt":97,"caption":98,"src":99},"Der Lesezugriff eines Besuchers kommt bei einer Policy an, gezeichnet als Schloss. Die Policy schickt eine Frage an die Tabelle profiles und die Tabelle schickt sie zurück an die Policy, und dieses Pfeilpaar bildet einen geschlossenen Kreis mit der Marke 42P17.","Mit der Anfrage ist alles in Ordnung. Der Kreis liegt zwischen der Regel und der Tabelle, die die Regel schützt.","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fthe-circle-1600x660.png",[10,101,102],{},"Supabases eigener Row-Level-Security-Leitfaden nennt die Variante mit zwei\nTabellen: Policies auf zwei Tabellen, die jeweils die andere lesen, lösen sich\nnie auf, und die Abfrage scheitert für jede Rolle, für die die Policies gelten.\nEine Tabelle, die sich selbst liest, ist dieselbe Form ohne den Umweg.",[33,104,106],{"id":105},"warum-passiert-das-immer-an-der-profiles-tabelle","Warum passiert das immer an der profiles-Tabelle?",[10,108,109,110,112],{},"Weil in ",[21,111,48],{}," steht, wer diese Person ist.",[10,114,115,116,118],{},"Jede Regel, die eine Sorte Mensch anders behandelt als eine andere, muss\nherausfinden, welche Sorte der Aufrufer ist, und diese Angabe liegt in einer\nSpalte irgendeiner Tabelle. Wie diese Tabelle auch heißt, die Regel, die sie\nschützt, liest am Ende sie. In einer App aus Lovable, Bolt, v0 oder Replit ist\ndas meistens ",[21,117,48],{},", weil dort die Zeile über jede angemeldete Person\nlandet. Eine Regel über Teams, Organisationen oder geteilte Dokumente erzeugt\ndenselben Kreis auf der Tabelle, in der die Mitgliedschaft steht.",[10,120,121],{},"Die Rekursion entsteht also daraus, dass du die naheliegende Regel über die\neine Tabelle geschrieben hast, die eine Frage über sich selbst beantworten muss.",[33,123,125],{"id":124},"der-fix-ein-helfer-der-die-tabelle-außerhalb-der-regeln-liest","Der Fix: ein Helfer, der die Tabelle außerhalb der Regeln liest",[10,127,128,129,131,132,134],{},"Verlege die Frage in eine kleine Funktion, die als Eigentümer der Datenbank\nläuft, damit das Lesen von ",[21,130,48],{}," für diese Antwort nicht durch die Regel\nauf ",[21,133,48],{}," geht.",[14,136,139],{"className":137,"code":138,"language":75,"meta":23},[73],"create schema if not exists private;\n\ncreate function private.is_admin()\nreturns boolean\nlanguage sql\nsecurity definer      -- läuft als die Rolle, die sie erstellt hat\nset search_path = ''  -- damit jeder Name darin voll ausgeschrieben werden muss\nstable\nas $$\n  select exists (\n    select 1 from public.profiles\n    where id = (select auth.uid()) and role = 'admin'\n  );\n$$;\n\nrevoke execute on function private.is_admin() from public;\ngrant usage on schema private to authenticated;\ngrant execute on function private.is_admin() to authenticated;\n\n-- Die Regel fragt jetzt die Funktion statt der Tabelle.\ncreate policy \"admins read every profile\" on profiles for select\nto authenticated\nusing ( (select private.is_admin()) );\n",[21,140,138],{"__ignoreMap":23},[10,142,143],{},"Der Türsteher hat die Gästeliste jetzt auf einem Tisch im Flur. Er liest sie,\nohne die Tür zu öffnen, und die Tür bleibt für alle zu, die nicht darauf stehen.",[10,145,146],{},"Vier Zeilen darin tun bestimmte Arbeit, und drei davon sind der Unterschied\nzwischen einem Fix und einem neuen Loch:",[148,149,150,163,179,188],"ul",{},[151,152,153,158,159,162],"li",{},[28,154,155],{},[21,156,157],{},"security definer"," ist das, was den Kreis bricht. Supabases Leitfaden\ndefiniert es als eine Funktion, die unter derselben Rolle läuft, die die\nFunktion erstellt hat, und auf Supabase ist diese Rolle ",[21,160,161],{},"postgres",", die an den\nRegeln vorbeilesen darf.",[151,164,165,170,171,174,175,178],{},[28,166,167],{},[21,168,169],{},"set search_path = ''"," gehört an jede einzelne davon. Supabase rät, es auf\njeder security definer Funktion zu setzen und die Tabellennamen voll\nauszuschreiben, denn ohne festgenagelten ",[21,172,173],{},"search_path"," kann ein Aufrufer einen\nunqualifizierten Namen auf ein eigenes Objekt zeigen lassen und ihn mit den\nRechten des Funktionseigentümers laufen lassen. Deshalb schreibt die Funktion\n",[21,176,177],{},"public.profiles"," voll aus.",[151,180,181,187],{},[28,182,183,184],{},"Das Schema ",[21,185,186],{},"private"," ist aus demselben Grund wichtig. Supabases Leitfaden\nwarnt, dass eine security definer Funktion in einem veröffentlichten Schema\nüber die Data API mit den Rechten ihres Erstellers aufgerufen werden kann, und\nsagt dir, niemals eine in einem Schema anzulegen, das in deinen\nAPI-Einstellungen unter Exposed schemas steht.",[151,189,190,195,196,199],{},[28,191,192],{},[21,193,194],{},"(select private.is_admin())",", in ein eigenes select gewickelt. Dadurch\nrechnet Postgres die Antwort einmal für die ganze Anweisung aus statt einmal\npro Zeile, was Supabase als Grund dokumentiert, ",[21,197,198],{},"auth.uid()"," genauso zu\nwickeln.",[10,201,202,203,206,207,210],{},"Die Zeilen ",[21,204,205],{},"revoke"," und ",[21,208,209],{},"grant"," halten die Funktion für angemeldete Nutzer\naufrufbar und für sonst niemanden.",[10,212,213,214,219],{},"Diese Policy deckt das Lesen ab. Wenn das Speichern zu scheitern beginnt,\nsobald deine Bildschirme sich wieder füllen, bist du\n",[215,216,218],"a",{"href":217},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","einer anderen Meldung mit einer anderen Ursache","\nbegegnet.",[33,221,223],{"id":222},"der-fix-der-keiner-ist","Der Fix, der keiner ist",[10,225,226,227,229],{},"Row Level Security auf ",[21,228,48],{}," abzuschalten beendet den Fehler ebenfalls, mit\neinem Klick, und es gibt jede Zeile dieser Tabelle an jeden weiter, der den\nSchlüssel hat, den deine App an den Browser ausliefert.",[10,231,232],{},"Dieser Schlüssel ist als öffentlich gedacht. Er steht im Code deiner Seite, und\njeder kann ihn in ein paar Sekunden herauslesen. Was ihn bisher davon abgehalten\nhat, deine ganze Nutzertabelle zurückzugeben, waren die Regeln, die du gerade\nabgeschaltet hast.",[95,234],{"alt":235,"caption":236,"src":237},"Zwei Wege zu derselben Tabelle. Im ersten steht das Schloss noch und eine Hilfsfunktion daneben gibt zwei von sechs Zeilen zurück. Im zweiten ist die Stelle des Schlosses nur noch ein leerer gestrichelter Umriss und alle sechs Zeilen kommen rot zurück.","Beide beenden den Fehler. Nur einer von beiden beantwortet die Frage noch, die der Regel gestellt wurde.","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Ftwo-ways-out-1600x700.png",[10,239,240],{},"Deine App sieht danach in beiden Fällen gleich aus, und genau das macht diese\nSache so hartnäckig. Nichts auf deinen Bildschirmen sagt, welche der beiden\nVarianten du gewählt hast, und der Fehler ist in beiden weg.",[10,242,243],{},"Was es sagt, ist deine Datenbank, von außen gefragt. Wir haben 31.056 live\ngeschaltete Apps aus Lovable, Bolt, v0, Replit und dem Rest gescannt und hinter\n8.435 davon ein Supabase-Projekt gesehen. Das hat die\nRow-Level-Security-Prüfung gefunden:",[245,246,247,260],"table",{},[248,249,250],"thead",{},[251,252,253,257],"tr",{},[254,255,256],"th",{},"Was wir gefragt haben",[254,258,259],{},"Apps",[261,262,263,272,280,288],"tbody",{},[251,264,265,269],{},[266,267,268],"td",{},"Hatten ein sichtbares Supabase-Projekt",[266,270,271],{},"8.435",[251,273,274,277],{},[266,275,276],{},"Konnten überhaupt gefragt werden",[266,278,279],{},"3.680",[251,281,282,285],{},[266,283,284],{},"Gaben Zeilen an eine Anfrage ohne Login zurück",[266,286,287],{},"2.096",[251,289,290,293],{},[266,291,292],{},"Davon aus einer Tabelle für Personen, Bestellungen, Nachrichten",[266,294,295],{},"394",[10,297,298],{},"Die mittlere Zeile ist die ehrliche. Bei 4.755 dieser Apps bekam die Prüfung\nkeine Antwort, und wir sagen das, statt sie für sauber zu erklären. Und einige\nder 2.096 sollen lesbar sein, denn eine öffentliche Tabelle ist etwas, das man\nwirklich wollen kann; von außen sehen eine Speisekarte und eine Mitgliederliste\ngleich aus.",[10,300,301],{},"Wir können dir nicht sagen, wie viele dieser Tabellen jemand beim Beheben genau\ndieses Fehlers geöffnet hat. Wir können dir sagen, dass eine offene Tabelle der\ngewöhnliche Endzustand des Rats ganz oben in den Suchergebnissen ist.",[10,303,304,305,309],{},"Wenn du lieber nicht darüber nachdenken willst: unser kostenloser Scan liest\ndeine Live-Seite und sagt dir, welche deiner Tabellen einem Fremden antworten.\nEr dauert etwa 20 Sekunden und braucht kein Konto:\n",[215,306,308],{"href":307},"\u002Fsecurity-scanner","scanne deine App",".",[10,311,312,313,317],{},"Noch etwas passiert, wenn du es abschaltest. Supabases eigener Advisor fängt an,\ndie Tabelle zu melden, das ist die Warnung\n",[215,314,316],{"href":315},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","RLS disabled in public",", und diese\nWarnung steht in einem Monat immer noch da.",[33,319,321],{"id":320},"wie-du-merkst-ob-der-kreis-wirklich-weg-ist","Wie du merkst, ob der Kreis wirklich weg ist",[10,323,324],{},"Dass der Fehler aufhört, ist nicht der Test, denn zwei verschiedene Dinge lassen\nihn aufhören.",[10,326,327,328,330,331,334],{},"Es gibt außerdem einen Weg, auf dem die Hilfsfunktion richtig aussieht und\ntrotzdem weiter rekursiv bleibt, und Supabase dokumentiert ihn: eine security\ndefiner Funktion geht nur dann an den Regeln vorbei, wenn ihr Eigentümer das\ndarf. Auf Supabase ist der Eigentümer ",[21,329,161],{},", der dieses Recht hat, also\nfunktioniert das Muster oben. Eine Funktion, die einer Rolle ohne dieses Recht\ngehört, oder eine, die eine Tabelle mit ",[21,332,333],{},"force row level security"," liest, geht\nwieder durch die Regel und bleibt im Kreis.",[10,336,337],{},"Zwei Prüfungen, und mach beide:",[10,339,340,343,344,347,348,351,352,355],{},[28,341,342],{},"Schreib die Fälle auf und lass sie laufen."," Supabases Verfahren ist eine\n",[21,345,346],{},".sql","-Datei unter ",[21,349,350],{},"supabase\u002Ftests\u002F",", die für jede Operation erlaubt und\nverboten behauptet, für einen angemeldeten Nutzer und für einen anonymen,\nausgeführt mit ",[21,353,354],{},"supabase test db",". Ein Admin muss jedes Profil sehen, ein\nMitglied sein eigenes, ein Fremder nichts. Bis das durchläuft, weißt du nur,\ndass der Fehler aufgehört hat.",[10,357,358,361,362,366,367,371],{},[28,359,360],{},"Dann frag von außen, ohne Login."," Das ist die Frage, die der Browser eines\nBesuchers stellt, und die einzige, die abbildet, was deine App tatsächlich\nherausgibt. ",[215,363,365],{"href":364},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Ob ein Fremder deine Datenbank lesen kann","\ngeht das durch, und\n",[215,368,370],{"href":369},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Row Level Security kann an sein und die Tabelle trotzdem öffentlich","\nbehandelt den Fall, in dem die Regeln da sind und trotzdem alle durchlassen.",[33,373,375],{"id":374},"wenn-die-rekursion-sagt-dass-das-schema-falsch-ist","Wenn die Rekursion sagt, dass das Schema falsch ist",[10,377,378],{},"Manchmal gibt es keine kreisförmige Frage zum Entfernen, weil die beiden\nTabellen wirklich voneinander abhängen.",[10,380,381,382,385,386,389,390,392,393,395],{},"Supabases Leitfaden nimmt das Teilen als Beispiel: eine Regel auf ",[21,383,384],{},"lists"," prüft\n",[21,387,388],{},"list_members",", um zu sehen, mit wem die Liste geteilt wurde, und eine Regel auf\n",[21,391,388],{}," prüft ",[21,394,384],{},", um zu sehen, wem sie gehört. Die Regel jeder\nTabelle liest die andere, und keine kann zuerst. Derselbe Helfer bricht das auf,\nmit einer Funktion, die die Listen-Ids zurückgibt, zu denen der Aufrufer gehört,\nund beiden Regeln, die diese Funktion fragen statt einander.",[10,397,398],{},"Das Signal, auf das es sich zu achten lohnt, ist, wenn du drei oder vier davon\nbrauchst, damit ein Schema funktioniert. An dem Punkt wird die Mitgliedschaft\njedes Mal innerhalb der Regeln neu gebaut, und eine einzelne Tabelle, die klar\nsagt, wer was sehen darf, ist meistens weniger Pflege als die Regeln, die du\ngerade entwirrst.",[33,400,402],{"id":401},"die-tabelle-zu-halten-nachdem-du-sie-repariert-hast","Die Tabelle zu halten, nachdem du sie repariert hast",[10,404,405,408],{},[28,406,407],{},"Eine Regel, die du heute repariert hast, beschreibt die Datenbank von heute.","\nDie nächste Policy, die nächste Tabelle und das nächste Mal, dass jemand um\nMitternacht einen Fehler wegklickt, passieren alle, nachdem du zuletzt\nhingesehen hast, und keines davon ändert etwas, das du auf deinen Bildschirmen\nsehen kannst.",[10,410,411],{},[28,412,413,417],{},[215,414,416],{"href":415},"\u002Fpricing","Reeve Monitor"," stellt deiner App dieselben Fragen noch einmal, nach\nPlan:",[148,419,420,423,430,433],{},[151,421,422],{},"alle neun Prüfungen jede Stunde, für bis zu drei Apps",[151,424,425,426,429],{},"eine Nachricht, wenn sich ein Ergebnis ",[28,427,428],{},"ändert",", damit eine Tabelle, die heute Nacht aufgegangen ist, nicht wartet, bis du es merkst",[151,431,432],{},"ob die App erreichbar ist, alle 60 Sekunden",[151,434,435],{},"ein monatlicher Bericht über das Gesehene",[10,437,438,446],{},[28,439,440,441,445],{},"Wenn deine App ihre Daten in deinem eigenen Supabase-Projekt hält, hält\n",[215,442,444],{"href":443},"\u002Fsupabase-backups","Reeve Care"," zusätzlich eine Kopie dieser Datenbank."," Eine\nRegel, die einen Fremden lesen lässt, ist das eine Problem. Eine Regel, die\neinen Fremden schreiben lässt, ist das andere, und keine Prüfung aus diesem\nArtikel holt gelöschte Zeilen zurück.",[148,448,449,452,455,458,461],{},[151,450,451],{},"eine verschlüsselte Kopie deiner Supabase-Datenbank jede Nacht, dort abgelegt, wo dein Projekt nicht hinkommt",[151,453,454],{},"jede Kopie geprüft, bevor sie zählt, durch Zählen der Zeilen in jeder Tabelle",[151,456,457],{},"eine Wiederherstellung per Klick, wenn du sie brauchst",[151,459,460],{},"deine hochgeladenen Dateien ebenfalls, sobald du eine Storage-Zugangsberechtigung verbindest",[151,462,463],{},"alles, was Monitor tut",[33,465,467],{"id":466},"was-du-jetzt-tun-kannst","Was du jetzt tun kannst",[469,470,471],"key-takeaways",{},[148,472,473,476,485,491,500],{},[151,474,475],{},"Lass Row Level Security an. Der Fehler betrifft eine Regel, und die Regeln abzuschalten ist eine Änderung an der ganzen Tabelle.",[151,477,478,479,481,482,484],{},"Verlege die Rollenprüfung in eine ",[21,480,157],{}," Funktion in einem nicht veröffentlichten Schema, mit ",[21,483,169],{}," und jedem Tabellennamen voll ausgeschrieben.",[151,486,487,488,490],{},"Zeige die Policy auf die Funktion, gewickelt als ",[21,489,194],{},", damit sie einmal pro Anweisung läuft statt einmal pro Zeile.",[151,492,493,494,496,497,499],{},"Schreib die erlaubten und verbotenen Fälle unter ",[21,495,350],{}," und führe ",[21,498,354],{}," aus: ein Admin sieht jedes Profil, ein Mitglied sein eigenes, ein Fremder nichts.",[151,501,502,503,309],{},"Wenn du Row Level Security schon abgeschaltet hast, um weiterzukommen, schalte es heute zurück und repariere die Regel richtig. Supabases Advisor meldet diese Tabelle weiter, bis du das tust, und ",[215,504,506],{"href":505},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","es gehört auf jede Tabelle, die du hast",[10,508,509,510,514],{},"Wenn du den Rest der Liste für eine frisch gestartete App willst: die\n",[215,511,513],{"href":512},"\u002Fchecklist","10-Minuten-Sicherheitscheckliste"," deckt das und die anderen Dinge\nab, die zu schließen sich lohnt, bevor sie jemand findet.",{"title":23,"searchDepth":516,"depth":516,"links":517},3,[518,520,521,522,523,524,525,526,527],{"id":35,"depth":519,"text":36},2,{"id":65,"depth":519,"text":66},{"id":105,"depth":519,"text":106},{"id":124,"depth":519,"text":125},{"id":222,"depth":519,"text":223},{"id":320,"depth":519,"text":321},{"id":374,"depth":519,"text":375},{"id":401,"depth":519,"text":402},{"id":466,"depth":519,"text":467},"Sicherheitsgrundlagen","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcover-1200x630.png","Eine verschlossene Tabellenfläche, deren eigener Schlüssel hinter dem Glas liegt, mit einem Riegel quer über der Tür.","\"Infinite recursion detected in policy for relation\" heißt: Deine Policy hat die Tabelle gefragt, die sie schützt. So brichst du den Kreis.",false,"md",[535,538,541,544,546],{"q":536,"a":537},"Was verursacht \"infinite recursion detected in policy for relation\"?","Eine Regel auf einer Tabelle, die genau diese Tabelle lesen muss, bevor sie antworten kann. Deine Regel sagt sinngemäß \"lass diese Person durch, wenn ihre Zeile in profiles sie als Admin ausweist\", also geht die Datenbank diese Zeile in profiles lesen, wofür sie die Regel auf profiles prüfen muss, was sie wieder zum Lesen derselben Zeile schickt. Postgres merkt, dass es im Kreis läuft, hört auf und meldet den Fehler 42P17. Dasselbe passiert über zwei Tabellen hinweg, deren Regeln jeweils die andere lesen.",{"q":539,"a":540},"Ist eine security definer Funktion in einer Policy sicher?","Ja, unter zwei Bedingungen, die Supabase in seinem eigenen Row-Level-Security-Leitfaden nennt. Setze search_path auf den leeren String und schreibe jeden Tabellennamen darin voll aus, also public.profiles statt profiles. Ohne das kann jemand einen unqualifizierten Namen auf ein eigenes Objekt zeigen lassen und es mit den Rechten des Funktionseigentümers laufen lassen. Und lege die Funktion in einem Schema an, das nicht über die API veröffentlicht ist, denn eine security definer Funktion in einem veröffentlichten Schema lässt sich von außen mit den Rechten ihres Erstellers aufrufen.",{"q":542,"a":543},"Soll ich RLS abschalten, um das zu beheben?","Das beendet den Fehler und öffnet die Tabelle. Mit abgeschaltetem Row Level Security kann jede Zeile darin von jedem gelesen werden, der den Schlüssel hat, den deine App an den Browser ausliefert, und diesen Schlüssel kann jeder aus deiner Seite herauslesen. Deine App verhält sich in beiden Fällen gleich, also sagt dir danach nichts mehr, welche der beiden Varianten du gewählt hast. Die Hilfsfunktion weiter unten beendet den Fehler und hält die Tabelle zu.",{"q":106,"a":545},"Weil in profiles üblicherweise die Antwort auf \"wer ist diese Person\" steht. Eine Regel, die Admins anders behandelt als andere, oder Mitglieder eines Teams anders, muss wissen, was der Aufrufer ist, und diese Angabe liegt in profiles. Also liest die Regel, die profiles schützt, am Ende profiles. Jede Tabelle, die Rolle oder Mitgliedschaft des Aufrufers hält, kann das auslösen, und in einer App aus Lovable, Bolt oder v0 ist das meistens die Tabelle namens profiles.",{"q":547,"a":548},"Wie prüfe ich, ob meine Policy wirklich funktioniert?","Zwei verschiedene Dinge beenden den Fehler, also sagt das Verschwinden des Fehlers für sich genommen wenig. Schreibe die erlaubten und die verbotenen Fälle in eine .sql-Datei unter supabase\u002Ftests\u002F und führe supabase test db aus, das ist das Verfahren, das Supabase mit dem Leitfaden veröffentlicht: ein angemeldeter Eigentümer muss durchkommen und ein Fremder muss abgewiesen werden. Stelle dann dieselbe Frage von außen an deine Datenbank, ganz ohne Login, so wie es der Browser eines Besuchers tut.","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",[551,552,553,554,555,556,557,558],"infinite recursion detected in policy for relation","supabase infinite recursion policy","infinite recursion rls supabase","supabase policy rekursion fehler","42P17 supabase","rls policy endlosschleife","supabase profiles policy rekursion","supabase rolle policy fehler",{},true,"Infinite recursion detected in policy","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","2026-10-08",{"title":5,"description":531},"blog\u002Finfinite-recursion-in-policy-for-relation",[567,568,569],"\"Infinite recursion detected in policy for relation\" ist der Postgres-Fehler 42P17. Eine Row-Level-Security-Regel auf einer Tabelle hat genau dieser Tabelle eine Frage gestellt, und die Frage hat kein Ende.","Das ist kein Zeichen dafür, dass Row Level Security falsch für deine App war. Es ist ein Zeichen dafür, dass eine Regel im Kreis gefragt hat.","Eine kleine Hilfsfunktion liest die Tabelle außerhalb der Regeln und bricht den Kreis. Row Level Security auf dieser Tabelle abzuschalten beendet den Fehler ebenfalls, indem es jede Zeile darin an jeden weitergibt, der den Schlüssel hat, der in deiner App mitgeliefert wird.","1kyqZ14w4lcrLK_2zhEtsGlyVDYiAOHQn_Q5rGRO6kc",[572,578,584,590,591,597,603,609,615,621,627,633,639,645,652,658,664,669,675,681,687,693,699,705,711,717,723,729,735,741,747,753,759,764,769,775,781,787,793,799,805,811,817,823,829,835,841,846,852,858,864,870,876,882,887,892,898,904,909,914,920],{"path":573,"title":574,"description":575,"published":576,"category":528,"image":577,"draft":532},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" beim Upload","\"New row violates row-level security policy for table objects\" heißt: Deinem Upload fehlt eine insert-Regel. Ein öffentlicher Bucket fügt keine hinzu.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":579,"title":580,"description":581,"published":582,"category":528,"image":583,"draft":532},"\u002Fblog\u002Fbase44-security-scan","Base44 Security Scan: das, was nur er sehen kann","Der Base44 Security Scan prüft sieben Arten von Problemen von innen. Hier ist die Hälfte, die er liest und sonst niemand, und die Hälfte, die er nie ansieht.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":585,"title":586,"description":587,"published":588,"category":528,"image":589,"draft":532},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Dein API-Key wurde geleakt. Die richtige Reihenfolge","Ein API-Key wurde geleakt und du weißt nicht, was zuerst zu tun ist. Nicht jeder Key im Frontend ist ein Leck, und die Reihenfolge zählt mehr als das Tempo.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":562,"title":5,"description":531,"published":563,"category":528,"image":549,"draft":532},{"path":592,"title":593,"description":594,"published":595,"category":528,"image":596,"draft":532},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" in Supabase, und die falsche Lösung","\"No API key found in request\" heißt, deine Supabase-Anfrage kam ohne Schlüssel an. Die meisten Antworten zeigen stattdessen auf deine Datenbankregeln.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":598,"title":599,"description":600,"published":601,"category":528,"image":602,"draft":532},"\u002Fblog\u002Fis-base44-safe","Ist Base44 sicher? Was 5.442 echte Base44-Apps zeigten","Ist Base44 sicher? Wir haben 5.442 laufende Base44-Apps mit neun Checks geprüft. Fast alle bekamen ein B, aus Gründen, die der Inhaber nie gewählt hat.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":604,"title":605,"description":606,"published":607,"category":528,"image":608,"draft":532},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","API-Schlüssel verstecken: ab in eine Supabase Edge Function","Einen API-Schlüssel verstecken heißt, ihn aus dem Browser zu nehmen. Eine Supabase Edge Function ist der kleinste Ort dafür, und zwei Schritte zählen mehr.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":610,"title":611,"description":612,"published":613,"category":528,"image":614,"draft":532},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Ist deine .env-Datei öffentlich? Zwölf Pfade zum Prüfen","Ist deine .env-Datei auf deinem eigenen Webserver öffentlich? Zwölf Adressen sagen es dir, und ein Treffer heißt: alles darin ist längst öffentlich.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":616,"title":617,"description":618,"published":619,"category":528,"image":620,"draft":532},"\u002Fblog\u002Fis-v0-safe","v0-Sicherheit: alle 1.790 gescannten v0-Apps bekamen ein A","v0-Sicherheit, gemessen an 1.790 laufenden v0-Apps: Jede bekam ein A. Nur 17 nannten eine Datenbank, und genau das misst das A vor allem.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":622,"title":623,"description":624,"published":625,"category":528,"image":626,"draft":532},"\u002Fblog\u002Fis-bolt-safe","Ist Bolt sicher? Was 1.123 echte Bolt-Apps zeigten","Ist Bolt sicher? Wir haben 1.123 laufende Bolt-Apps mit neun Checks geprüft. Das Hosting war sauber. Die Funde waren Schlüssel und offene Tabellen in den Apps.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":628,"title":629,"description":630,"published":631,"category":528,"image":632,"draft":532},"\u002Fblog\u002Fis-supabase-down-or-your-app","Ist Supabase down oder liegt es an deiner App? So erkennst du es","Ist Supabase down oder liegt es an deiner App? Ein pausiertes Projekt, eine volle Datenbank und ein eigener Fehler sehen gleich aus. Vier Prüfungen helfen.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":634,"title":635,"description":636,"published":637,"category":528,"image":638,"draft":532},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Verschlüsselt Supabase meine Daten? Ja. Wovor das schützt","Verschlüsselt Supabase Daten? Ja: AES-256 im Ruhezustand, TLS bei der Übertragung, SOC 2 und ISO 27001. Was jedes abdeckt und welches Leck keines stoppt.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":640,"title":641,"description":642,"published":643,"category":528,"image":644,"draft":532},"\u002Fblog\u002Fsupabase-free-plan-limits","Supabase Gratis-Tarif: die Limits und was an jedem passiert","Die Limits des Supabase-Gratis-Tarifs: 500 MB Datenbank, 5 GB Egress und keine Backups. Was an jeder Grenze passiert und was $25 für Pro ändern.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":646,"title":647,"description":648,"published":649,"category":650,"image":651,"draft":532},"\u002Fblog\u002Ftest-your-supabase-backup","Teste dein Supabase-Backup, bevor du es brauchst","So testest du dein Supabase-Backup: in ein Übungsprojekt einspielen, Zeilen zählen, anmelden und die Zeile suchen, die einer abgeschnittenen Datei fehlt.","2026-09-28","Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":653,"title":654,"description":655,"published":656,"category":650,"image":657,"draft":532},"\u002Fblog\u002Fsupabase-backup-github-action","Kostenloses Supabase-Backup per GitHub Action, mit Haken","Eine Supabase-Backup-GitHub-Action kostet nichts und passt für viele Apps. Der Workflow, der richtige Connection String und das Egress pro Lauf.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":659,"title":660,"description":661,"published":662,"category":650,"image":663,"draft":532},"\u002Fblog\u002Fdownload-your-supabase-backup","Warum du dein Supabase-Backup nicht herunterladen kannst","Dein Supabase-Backup kannst du auf aktuellen Projekten nicht herunterladen, weil die Tageskopie physisch ist. Wie du es prüfst und selbst eine Kopie hältst.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":665,"title":666,"description":667,"published":662,"category":528,"image":668,"draft":532},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": der fehlende Grant","Ab 30. Oktober antwortet eine neue Supabase-Tabelle mit \"permission denied for table\", bis du Zugriff erteilst. Der Grant aus der E-Mail ist die halbe Lösung.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":670,"title":671,"description":672,"published":673,"category":528,"image":674,"draft":532},"\u002Fblog\u002Fopen-api-endpoint-exposed","Ist ein offener API-Endpunkt ein Sicherheitsproblem? Sieh ins JSON","Dein Scan hat einen offenen API-Endpunkt gemeldet. Ob das zählt, hängt davon ab, was zurückkam, und die meisten hier gehörten der Plattform.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":676,"title":677,"description":678,"published":679,"category":528,"image":680,"draft":532},"\u002Fblog\u002Flovable-security-scan","Lovable Security Scan: das Eine, was er nicht beweist","Lovable Security Scan: was Quick Scan und Deep Scan prüfen, wann welcher läuft, und das Eine, was kein Scan von innen beweisen kann.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":682,"title":683,"description":684,"published":685,"category":650,"image":686,"draft":532},"\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","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":688,"title":689,"description":690,"published":691,"category":528,"image":692,"draft":532},"\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":694,"title":695,"description":696,"published":697,"category":528,"image":698,"draft":532},"\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":700,"title":701,"description":702,"published":703,"category":528,"image":704,"draft":532},"\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":706,"title":707,"description":708,"published":709,"category":528,"image":710,"draft":532},"\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":712,"title":713,"description":714,"published":715,"category":528,"image":716,"draft":532},"\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":718,"title":719,"description":720,"published":721,"category":528,"image":722,"draft":532},"\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":724,"title":725,"description":726,"published":727,"category":528,"image":728,"draft":532},"\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":730,"title":731,"description":732,"published":733,"category":528,"image":734,"draft":532},"\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":736,"title":737,"description":738,"published":739,"category":650,"image":740,"draft":532},"\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":742,"title":743,"description":744,"published":745,"category":650,"image":746,"draft":532},"\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":748,"title":749,"description":750,"published":751,"category":650,"image":752,"draft":532},"\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":754,"title":755,"description":756,"published":757,"category":528,"image":758,"draft":532},"\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":505,"title":760,"description":761,"published":762,"category":528,"image":763,"draft":532},"Row Level Security für jede Supabase-Tabelle aktivieren und prüfen","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.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":315,"title":765,"description":766,"published":767,"category":528,"image":768,"draft":532},"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":770,"title":771,"description":772,"published":773,"category":528,"image":774,"draft":532},"\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":776,"title":777,"description":778,"published":779,"category":528,"image":780,"draft":532},"\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":782,"title":783,"description":784,"published":785,"category":528,"image":786,"draft":532},"\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":788,"title":789,"description":790,"published":791,"category":528,"image":792,"draft":532},"\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":794,"title":795,"description":796,"published":797,"category":528,"image":798,"draft":532},"\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":800,"title":801,"description":802,"published":803,"category":528,"image":804,"draft":532},"\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":806,"title":807,"description":808,"published":809,"category":528,"image":810,"draft":532},"\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":812,"title":813,"description":814,"published":815,"category":650,"image":816,"draft":532},"\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":818,"title":819,"description":820,"published":821,"category":528,"image":822,"draft":532},"\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":824,"title":825,"description":826,"published":827,"category":650,"image":828,"draft":532},"\u002Fblog\u002Fback-up-supabase-free-tier","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":830,"title":831,"description":832,"published":833,"category":528,"image":834,"draft":532},"\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":836,"title":837,"description":838,"published":839,"category":528,"image":840,"draft":532},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","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":217,"title":842,"description":843,"published":844,"category":528,"image":845,"draft":532},"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":847,"title":848,"description":849,"published":850,"category":528,"image":851,"draft":532},"\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":853,"title":854,"description":855,"published":856,"category":650,"image":857,"draft":532},"\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":859,"title":860,"description":861,"published":862,"category":650,"image":863,"draft":532},"\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":865,"title":866,"description":867,"published":868,"category":528,"image":869,"draft":532},"\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":871,"title":872,"description":873,"published":874,"category":528,"image":875,"draft":532},"\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":877,"title":878,"description":879,"published":880,"category":650,"image":881,"draft":532},"\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":364,"title":883,"description":884,"published":885,"category":528,"image":886,"draft":532},"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":888,"title":889,"description":890,"published":885,"category":528,"image":891,"draft":532},"\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":893,"title":894,"description":895,"published":896,"category":528,"image":897,"draft":532},"\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":899,"title":900,"description":901,"published":902,"category":650,"image":903,"draft":532},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","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":369,"title":905,"description":906,"published":907,"category":528,"image":908,"draft":532},"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":910,"title":911,"description":912,"published":907,"category":650,"image":913,"draft":532},"\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":915,"title":916,"description":917,"published":918,"category":650,"image":919,"draft":532},"\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":921,"title":922,"description":923,"published":918,"category":528,"image":924,"draft":532},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","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",1791705957971]