[{"data":1,"prerenderedAt":921},["ShallowReactive",2],{"blog-de-open-api-endpoint-exposed":3,"blog-index-de":571},{"id":4,"title":5,"body":6,"category":529,"cover":530,"coverAlt":531,"description":532,"draft":533,"extension":534,"faq":535,"image":550,"keywords":551,"meta":559,"navigation":560,"ogTitle":561,"path":562,"published":563,"seo":564,"stem":565,"tldr":566,"updated":563,"__hash__":570},"blog_de\u002Fblog\u002Fopen-api-endpoint-exposed.md","Ist ein offener API-Endpunkt ein Sicherheitsproblem? Sieh ins JSON",{"type":7,"value":8,"toc":515},"minimark",[9,13,21,26,29,32,35,41,44,48,51,54,118,121,125,128,138,144,150,168,179,188,192,195,202,274,282,294,298,301,304,307,312,322,326,329,332,356,359,363,366,369,379,382,388,399,421,427,430,436,445,450,453,459,462,471,475,495,502],[10,11,12],"p",{},"Dein Scan kam mit einer Zeile zurück, die nicht wie ein Urteil klingt: einige\nAPI-Endpunkte antworten ohne Login. Vielleicht hat es dir auch jemand direkter\ngesagt und von einem offenen API-Endpunkt gesprochen. Darunter steht eine\nAdresse, und es ist gut möglich, dass du sie nicht wiedererkennst.",[10,14,15,16,20],{},"Hier ist der Teil, den Ratgeber um Ratgeber falsch darstellt: ",[17,18,19],"strong",{},"der übliche Rat\nzu diesem Befund lautet, einen Login vor deinen Endpunkt zu setzen, und bei den\nmeisten Apps, die wir gescannt haben, gibt es gar keinen Endpunkt von dir, vor\nden man einen setzen könnte."," Sieben von zehn der gefundenen gehören der\nPlattform, auf der die App veröffentlicht wurde. Diesen Befund zu lesen beginnt\nalso damit, herauszufinden, wessen Adresse das ist, und die Antwort steht\nmeistens schon in der ersten Zeile dessen, was zurückkommt.",[22,23,25],"h2",{"id":24},"was-ein-offener-api-endpunkt-in-deinem-bericht-bedeutet","Was ein offener API-Endpunkt in deinem Bericht bedeutet",[10,27,28],{},"Es bedeutet, dass ein Pfad aus dem Code deiner App eine Anfrage beantwortet hat,\ndie keinen Login mitführte, und dass JSON zurückkam.",[10,30,31],{},"Drei Schritte, und keiner davon ist raffiniert. Wir laden deine App in einem\nBrowser, so wie ein Besucher es tut, und lesen den Code, den dieser Browser\nheruntergeladen hat. Darin stehen die Adressen, die deine App aufruft, wenn sie\nDaten braucht. Dann fragen wir jede einzelne nach Daten, ohne Konto, ohne Cookie\nund ohne Schlüssel. Antwortet eine Adresse mit JSON, das keine Fehlermeldung\nist, landet sie im Bericht.",[10,33,34],{},"Das hält fest, was passiert ist. Es ist kein Urteil über die Daten, denn nichts,\nwas außerhalb deiner App steht, kann erkennen, ob eine Liste von Dingen eine\nListe öffentlicher Dinge ist. Deshalb ist der Befund so formuliert, wie er\nformuliert ist: diese Endpunkte gaben Daten ohne jede Authentifizierung zurück,\ndas kann bei öffentlichen Daten so gewollt sein, prüfe, dass keiner davon\nprivate Informationen preisgibt.",[36,37],"diagram",{"alt":38,"caption":39,"src":40},"Von einer App heruntergeladener Code, aus dem vier Adressen herausgegriffen sind. Jede Adresse wird von einer Anfrage nach Daten gefragt, die einen durchgestrichenen Schlüssel trägt, also keinen Login. Drei kommen leer oder abgewiesen zurück, eine kommt mit einem Datenblock zurück.","Die Adressen stammen aus deinem eigenen Code, und jede wird ohne alles gefragt. Was antwortet, landet im Bericht.","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fwhat-the-check-does-1600x620.png",[10,42,43],{},"Der Bericht reicht dir also eine Liste von Adressen zum Öffnen. Jede einzelne\ndavon gehört in einem abgemeldeten Browser geöffnet, und die ersten Zeilen der\nAntwort entscheiden die Sache.",[22,45,47],{"id":46},"ist-jeder-offene-api-endpunkt-ein-sicherheitsproblem","Ist jeder offene API-Endpunkt ein Sicherheitsproblem?",[10,49,50],{},"Nein. Es gibt drei Sorten, und nur die dritte ist ein Problem.",[10,52,53],{},"Denk an ein Mehrfamilienhaus. Manches darin ist für jeden gedacht, der\nhereinkommt: die Öffnungszeiten an der Tür, die Fluchtwege, der Aushang über die\nAufzugwartung am Dienstag. Irgendwo im selben Haus steht ein Aktenschrank mit\nden Daten der Mieter. Vom Flur aus sind ein Schwarzes Brett und ein\nunverschlossener Aktenschrank beide nur Mobiliar, das man öffnen kann, und\nauseinanderhalten kann man sie nur, indem man liest, was auf dem Papier steht.",[55,56,57,73],"table",{},[58,59,60],"thead",{},[61,62,63,67,70],"tr",{},[64,65,66],"th",{},"Was geantwortet hat",[64,68,69],{},"Wessen Adresse ist das",[64,71,72],{},"Wo du stehst",[74,75,76,92,104],"tbody",{},[61,77,78,82,85],{},[79,80,81],"td",{},"Plattform-Einstellungen: Cookie-Hinweise, Feature-Schalter",[79,83,84],{},"Die deines Builders, in jeder App, die er veröffentlicht",[79,86,87],{},[88,89,91],"key-verdict",{"type":90},"safe","Nichts zu tun",[61,93,94,97,100],{},[79,95,96],{},"Deine eigenen öffentlichen Daten: eine Preisliste, ein Artikel",[79,98,99],{},"Deine, und zum Lesen gedacht",[79,101,102],{},[88,103,91],{"type":90},[61,105,106,109,112],{},[79,107,108],{},"Zeilen über Personen: Namen, E-Mails, Bestellungen, Nachrichten",[79,110,111],{},"Deine, und erreichbar für jeden mit der Adresse",[79,113,114],{},[88,115,117],{"type":116},"danger","Heute schließen",[10,119,120],{},"Die erste Zeile ist ein Schwarzes Brett, das jemand anderes an die Wand\ngeschraubt hat. Die zweite ist ein Schwarzes Brett, das du absichtlich\naufgehängt hast. Die dritte ist der Aktenschrank, und er steht offen, solange es\ndie Adresse gibt.",[22,122,124],{"id":123},"so-prüfst-du-was-deine-endpunkte-zurückgeben","So prüfst du, was deine Endpunkte zurückgeben",[10,126,127],{},"Öffne jede abgemeldet und lies, was ankommt. Das Lesen dauert länger, als der\nBefund vermuten lässt, und es ist der einzige Schritt, der die Frage beantwortet.",[10,129,130,133,134,137],{},[17,131,132],{},"Finde die Adressen."," Öffne deine Live-App, drücke F12 für die\nEntwicklerwerkzeuge des Browsers, klicke auf ",[17,135,136],{},"Netzwerk"," und lade die Seite neu.\nKlicke die Anfragen durch, die als JSON zurückkommen. Das sind die Adressen, von\ndenen deine App Daten holt, und die Liste im Bericht ist eine Teilmenge davon.",[10,139,140,143],{},[17,141,142],{},"Frage jede als Fremder."," Kopiere eine URL, öffne ein privates Browserfenster,\ndamit du abgemeldet bist, und füge sie ein. Was du siehst, ist genau das, was\njeder im Internet an dieser Adresse sieht.",[10,145,146,149],{},[17,147,148],{},"Lies die ersten Zeilen."," Drei Dinge können zurückkommen:",[151,152,153,162,165],"ul",{},[154,155,156,157,161],"li",{},"Ein Fehler, eine Abweisung oder ",[158,159,160],"code",{},"[]",". Die Adresse will einen Login, oder für\neinen abgemeldeten Aufrufer ist nichts darin. Weiter.",[154,163,164],{},"Einstellungen. Flags, Schalter, eine Farbe, eine Liste aktivierter Funktionen,\neine Versionsnummer. Niemand wird genannt, nichts wird beschrieben. Weiter.",[154,166,167],{},"Zeilen. Eine E-Mail-Adresse, der Name einer Person, eine Bestellsumme, der\nText einer Nachricht, eine Telefonnummer. Hier anhalten, das ist die eine.",[10,169,170,171,174,175,178],{},"Wenn du Zeilen findest, ändere eine Zahl in der URL, bevor du den Tab schließt.\nEine Adresse, die bei ",[158,172,173],{},"id=1"," den Datensatz einer Person herausgibt und bei\n",[158,176,177],{},"id=2"," den einer anderen, gibt alle heraus, und das ist gut zu wissen, bevor du\nentscheidest, wie dringend das ist.",[10,180,181,182,187],{},"Unser kostenloser Scan erledigt die ersten beiden Schritte für dich: er liest im\nCode deiner App die Adressen, die sie aufruft, fragt jede ohne Login und listet\ndie auf, die mit Daten geantwortet haben. Er dauert etwa 20 Sekunden und\nbraucht kein Konto: ",[183,184,186],"a",{"href":185},"\u002Fsecurity-scanner","scanne deine App",". Der dritte Schritt\ngehört dir, denn nur du weißt, ob ein Name in dieser Liste ein echter Kunde ist.",[22,189,191],{"id":190},"die-meisten-die-wir-fanden-gehören-der-plattform","Die meisten, die wir fanden, gehören der Plattform",[10,193,194],{},"In unserem Sweep vom August 2026 hatten 3.852 der 30.926 Apps, bei denen diese\nPrüfung eine Antwort bekam, mindestens eine Adresse, die ohne Login antwortet.\nDavon waren 2.705 Base44-Apps, und bei Base44 ist es fast immer dieselbe\nAdresse.",[10,196,197,198,201],{},"Es ist ",[158,199,200],{},"\u002Fapi\u002Fconsent\u002Fconfig",", die Cookie-Einstellungen der Plattform. Wir haben\nim September eine Stichprobe gemeldeter Base44-Apps erneut geöffnet, und die\neinzige Adresse, die antwortete, war diese. Sie gibt Einstellungen zurück, sie\nist auf allen Apps identisch, und niemandes Daten stecken darin. Der Scanner\nmeldet sie korrekt, und der Betreiber hat nichts zu beheben.",[55,203,204,217],{},[58,205,206],{},[61,207,208,211,214],{},[64,209,210],{},"Plattform",[64,212,213],{},"Apps mit dem Befund",[64,215,216],{},"Apps, bei denen die Prüfung antwortete",[74,218,219,230,241,252,263],{},[61,220,221,224,227],{},[79,222,223],{},"Base44",[79,225,226],{},"2.705",[79,228,229],{},"5.419",[61,231,232,235,238],{},[79,233,234],{},"Eigene Domains",[79,236,237],{},"82",[79,239,240],{},"955",[61,242,243,246,249],{},[79,244,245],{},"Bolt",[79,247,248],{},"4",[79,250,251],{},"1.120",[61,253,254,257,260],{},[79,255,256],{},"Lovable",[79,258,259],{},"8",[79,261,262],{},"18.518",[61,264,265,268,271],{},[79,266,267],{},"v0",[79,269,270],{},"0",[79,272,273],{},"1.786",[10,275,276,277,281],{},"Eine Plattform fehlt in dieser Tabelle mit Absicht. Auf Replit entfällt ein\ngroßer Block der übrigen Befunde, und niemand hat davon eine Stichprobe erneut\ngeöffnet, so wie wir es bei Base44 getan haben, also wissen wir noch nicht,\nwessen Adressen das sind. Eine Zahl als Problem des Betreibers zu veröffentlichen,\nbevor jemand hingesehen hat, ist genau der Weg, auf dem eine\nPlattform-Einstellung von Base44 zur Statistik über nachlässige Betreiber wird.\nJede Zahl hier oben stammt aus\n",[183,278,280],{"href":279},"\u002Fresearch\u002Fvibe-coded-app-security-2026","unserem Scan von 30.998 live geschalteten Vibe-Coding-Apps",",\nder zu jeder die Basis mitveröffentlicht, über der sie gemessen wurde.",[10,283,284,285,288,289,293],{},"Lies die beiden Enden dieser Tabelle zusammen, denn die Spreizung ist der\nnützliche Teil. Bei Lovable sind es 8 Apps von 18.518, bei v0 überhaupt keine.\nDiese Apps haben keinen kleinen eigenen Server: die Seite spricht direkt aus dem\nBrowser mit Supabase, es gibt also nirgends ein ",[158,286,287],{},"\u002Fapi\u002F…"," von dir, das diese\nPrüfung finden könnte. Was die Daten in so einer App schützt, sind die Regeln\nauf jeder Tabelle, und das ist ein anderer Befund mit einer\n",[183,290,292],{"href":291},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","eigenen Art, schiefzugehen",".",[22,295,297],{"id":296},"wann-das-json-einstellungen-sind-und-wann-personen","Wann das JSON Einstellungen sind und wann Personen",[10,299,300],{},"Eine Frage entscheidet: beschreibt irgendetwas in der Antwort eine Person?",[10,302,303],{},"Einstellungen beschreiben deine App. Ein Flag dafür, ob der Dunkelmodus an ist,\ndie Liste der Währungen, die du annimmst, die Version von irgendetwas, der Text\nfür ein Cookie-Banner. Das zu veröffentlichen verrät, wie deine App konfiguriert\nist, und deine App läuft ohnehin vor aller Augen.",[10,305,306],{},"Zeilen beschreiben deine Nutzer. Ein Name, eine E-Mail-Adresse, was jemand\ngekauft hat, was er geschrieben hat, wo er wohnt. Das ist kein Satz über eine\nKonfiguration, das ist der Inhalt des Aktenschranks, und es zählt deshalb, weil\nes so alltäglich ist, ihn mitzunehmen. Es gibt keinen Einbruch. Die Adresse ist\neine Textzeile, die in jedem Browser funktioniert, also wird sie in einen\nGruppenchat kopiert, in jemandes Notizen gespeichert und von einem Skript, das\nniemand beobachtet, im Takt abgerufen.",[36,308],{"alt":309,"caption":310,"src":311},"Zwei Antworten von gleicher Größe und Form. Die linke enthält vier Schalter, zwei an und zwei aus. Die rechte enthält vier Zeilen, jede mit einer Personenfigur und einer geschwärzten Zeile daneben.","Beides ist eine 200 und ein Block JSON, und mehr sieht die Prüfung nicht. Der Unterschied dazwischen ist die ganze Frage, und beantworten kannst du sie durch Lesen.","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fsettings-or-people-1600x660.png",[313,314,316],"callout",{"type":315},"note",[10,317,318,321],{},[17,319,320],{},"Der unangenehme Fall ist die Adresse, die früher Einstellungen war."," Ein\nEndpunkt, der eine Liste der Kategorien deiner App zurückgab, war an dem Tag,\nan dem er geschrieben wurde, öffentliche Daten. Dann hat jemand der Tabelle\ndahinter eine Spalte hinzugefügt, damit die Seite anzeigen kann, wer jede\nKategorie angelegt hat, und dieselbe Adresse gab plötzlich Namen heraus. Auf dem\nBildschirm änderte sich nichts, die Adresse wanderte nicht, und der Befund in\ndeinem Bericht liest sich genauso wie vorher.",[22,323,325],{"id":324},"einen-schließen-und-warum-umbenennen-ihn-nicht-schließt","Einen schließen, und warum Umbenennen ihn nicht schließt",[10,327,328],{},"Verlange an der Adresse einen Login, und antworte einem Aufrufer, der keinen\nhat, mit einer 401.",[10,330,331],{},"Das ist die ganze Behebung, und sie gehört an die Adresse und nirgendwo sonst.\nDrei Dinge, die wie die Behebung aussehen und keine sind:",[151,333,334,340,350],{},[154,335,336,339],{},[17,337,338],{},"Den Pfad umbenennen oder ihn aus deinem Code nehmen."," Bei diesem ist\nVorsicht geboten, weil der Befund verschwindet. Wer die URL schon hatte, hat\nsie weiterhin, sie steht in Browser-Verläufen und Server-Logs, und der\nAktenschrank ist immer noch offen, nur ohne Schild an der Front.",[154,341,342,345,346,293],{},[17,343,344],{},"Deinen CORS-Header verengen."," Der regelt, welche anderen Websites eine\nAntwort im Browser von jemandem lesen dürfen, und sonst schaut ihn nichts an.\nEin Skript oder ein Terminal liest dieselbe Adresse so oder so, weshalb\n",[183,347,349],{"href":348},"\u002Fblog\u002Fcors-wildcard-security-risk","der Wildcard-Befund eine andere Frage ist",[154,351,352,355],{},[17,353,354],{},"In der App filtern."," Wenn die Seite die Zeilen versteckt, die sie nicht\nzeigen soll, schickt die Adresse sie trotzdem. Gefiltert werden muss, bevor\ndie Antwort hinausgeht.",[10,357,358],{},"Es gibt eine vierte Möglichkeit, und auf einer öffentlichen Seite ist sie oft\ndie beste: den Endpunkt abschaffen. Wenn die Daten ohnehin nur für deine eigene\nSeite sind, kann die Seite sie beim Bauen bekommen, und die Adresse verschwindet\ndabei aus deinem Code.",[22,360,362],{"id":361},"wie-die-behebung-im-code-aussieht","Wie die Behebung im Code aussieht",[10,364,365],{},"Zwei Dinge, im Handler, der die Adresse beantwortet: herausfinden, wer fragt,\nund aufhören, wenn die Antwort niemand lautet.",[10,367,368],{},"Vielleicht tippst du das nie selbst, und das ist in Ordnung. Lies es trotzdem,\ndenn daran prüfst du, ob dein Builder wirklich getan hat, worum du ihn gebeten\nhast. Das hier ist die Form davor, und das ist, was der Scan gefunden hat:",[370,371,376],"pre",{"className":372,"code":374,"language":375},[373],"language-text","app.get('\u002Fapi\u002Forders', async (req, res) => {\n  const orders = await db.orders.findMany()\n  res.json(orders)\n})\n","text",[158,377,374],{"__ignoreMap":378},"",[10,380,381],{},"Und danach:",[370,383,386],{"className":384,"code":385,"language":375},[373],"app.get('\u002Fapi\u002Forders', async (req, res) => {\n  const user = await getUserFromRequest(req)\n  if (!user) {\n    return res.status(401).json({ error: 'Not signed in' })\n  }\n\n  const orders = await db.orders.findMany({ where: { userId: user.id } })\n  res.json(orders)\n})\n",[158,387,385],{"__ignoreMap":378},[10,389,390,391,394,395,398],{},"Zwei Dinge haben sich geändert, und beide zählen. Die ",[158,392,393],{},"401"," ist die Tür. Das\n",[158,396,397],{},"where"," ist der Grund, warum sich die Tür lohnt: ohne es kann ein angemeldeter\nBesucher die Bestellungen aller anderen Kunden lesen, was ein kleineres Publikum\nfür dieselben Daten ist und immer noch das falsche.",[10,400,401,404,405,408,409,412,413,416,417,420],{},[17,402,403],{},"Bei Supabase Edge Functions lies erst die Konfiguration, bevor du irgendetwas\nschreibst."," Edge Functions prüfen das Token des Aufrufers von sich aus: die\nKonfigurationsreferenz von Supabase setzt ",[158,406,407],{},"verify_jwt"," standardmäßig auf ",[158,410,411],{},"true",",\neine Funktion, die Fremden antwortet, ist also eine, bei der das jemand\nabgeschaltet hat, entweder mit einer Zeile in ",[158,414,415],{},"supabase\u002Fconfig.toml"," oder beim\nDeployen mit ",[158,418,419],{},"--no-verify-jwt",":",[370,422,425],{"className":423,"code":424,"language":375},[373],"[functions.orders]\nverify_jwt = false\n",[158,426,424],{"__ignoreMap":378},[10,428,429],{},"Wenn deine Funktion privat sein soll, lösche diese zwei Zeilen und deploye neu.\nLass sie nur dort stehen, wo der Endpunkt wirklich jedem antworten muss, und das\nist der Fall, den die Dokumentation von Supabase selbst als Beispiel nimmt: ein\nZahlungs-Webhook. Innerhalb der Funktion gibt dir das aktuelle SDK einen\nClient, der bereits auf die Person zugeschnitten ist, die aufgerufen hat:",[370,431,434],{"className":432,"code":433,"language":375},[373],"import { withSupabase } from 'npm:@supabase\u002Fserver'\n\nexport default {\n  fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {\n    const { data } = await ctx.supabase.from('orders').select()\n    return Response.json(data)\n  }),\n}\n",[158,435,433],{"__ignoreMap":378},[10,437,438,441,442,293],{},[158,439,440],{},"ctx.supabase"," läuft als der Aufrufer, deine Row-Level-Security-Regeln\nentscheiden also, was zurückkommt, und das ist derselbe Schutz, auf den sich der\nRest deiner App verlässt, sowie\n",[183,443,444],{"href":291},"die Sache, die man getrennt prüfen sollte",[446,447,449],"h3",{"id":448},"der-prompt-zum-einfügen-in-deinen-builder","Der Prompt zum Einfügen in deinen Builder",[10,451,452],{},"Wenn du in Lovable, Bolt, Cursor, Replit oder v0 baust, gib ihm das hier. Lass\nes auf Englisch, in welcher Sprache du das hier auch liest, denn in dieser\nSprache denken diese Werkzeuge, und ersetze die beiden Teile in Klammern durch\ndas, was dein eigener Bericht sagt:",[370,454,457],{"className":455,"code":456,"language":375},[373],"A security scan of [my-app.com] found these API endpoints answer\nwithout any authentication: [\u002Fapi\u002Forders, \u002Fapi\u002Fusers].\n\nPlease look at each one and decide whether it is meant to be public.\nFor the ones that are not, require a valid session or API token and\nreturn 401 otherwise. Make sure each one returns only the rows that\nbelong to the person asking, not the whole table filtered in the UI.\nFor any that must stay open, make sure they return only non-sensitive\ndata and add rate limiting so they cannot be abused.\n\nTell me what you changed for each endpoint, and do not rename or\nremove the paths.\n",[158,458,456],{"__ignoreMap":378},[10,460,461],{},"Der letzte Satz steht dort mit Absicht. Wird ein Modell gebeten, einen Befund\nverschwinden zu lassen, nimmt es manchmal den kürzesten Weg und verschiebt die\nAdresse, und das ist das eine Ergebnis, das beim erneuten Scan wie Erfolg\naussieht und nichts ändert.",[313,463,465],{"type":464},"warn",[10,466,467,470],{},[17,468,469],{},"Scanne abgemeldet nach, nicht angemeldet."," Ist die Behebung deployt, prüfe\nsie so, wie der Abschnitt oben es beschreibt: ein privates Browserfenster und\ndie URL. Angemeldet zu testen beweist, dass der Endpunkt für dich noch\nfunktioniert, und daran bestand nie ein Zweifel. Melde dich ab und lies es\nnoch einmal.",[22,472,474],{"id":473},"was-du-jetzt-tun-solltest","Was du jetzt tun solltest",[476,477,478],"key-takeaways",{},[151,479,480,483,486,489,492],{},[154,481,482],{},"Öffne jede gemeldete Adresse in einem privaten Browserfenster und lies, was zurückkommt. Das ist der Schritt, den der Bericht dir nicht abnehmen kann.",[154,484,485],{},"Sind es Einstellungen und ist die Adresse eine, die du nie geschrieben hast, gehört sie deinem Builder und es gibt nichts zu beheben. Prüfe den Pfad in der Doku deiner Plattform, bevor du Geld dafür ausgibst.",[154,487,488],{},"Enthält die Antwort einen Namen, eine E-Mail oder eine Bestellung, verlange an dieser Adresse noch heute einen Login und gib jedem ohne Login eine 401 zurück.",[154,490,491],{},"Benenne den Pfad nicht um und lösche den Verweis darauf nicht. Der Befund verschwindet, und die Adresse antwortet weiter.",[154,493,494],{},"Ändere in deiner eigenen App eine ID in der URL. Eine Adresse, die einem Fremden einen Datensatz gibt, gibt ihm meist alle.",[10,496,497,498,293],{},"Die Adressen auf dieser Liste hat jemand geschrieben, der damals wusste, was\ndahinter lag, und was sich ändert, ist das, was dahinter liegt. Reeve Care führt\ndiesen Scan nach einem Zeitplan erneut gegen deine Live-App aus und schickt dir\neine E-Mail, wenn ein Ergebnis schlechter wird, und genau diesen Fall kann der\nabgemeldete Durchgang oben nicht fangen:\n",[183,499,501],{"href":500},"\u002Fpricing","was Care überwacht und was es kostet",[10,503,504,505,509,510,514],{},"Wenn du lieber alles in einem Durchgang abarbeitest: die\n",[183,506,508],{"href":507},"\u002Fchecklist","Sicherheits-Checkliste in 10 Minuten"," deckt das hier neben allem\nanderen ab, was eine frisch gestartete App gern offen lässt, und\n",[183,511,513],{"href":512},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","welche Schlüssel im Frontend sicher sind","\nist der andere Befund, mit dem Leute meistens ankommen.",{"title":378,"searchDepth":516,"depth":516,"links":517},3,[518,520,521,522,523,524,525,528],{"id":24,"depth":519,"text":25},2,{"id":46,"depth":519,"text":47},{"id":123,"depth":519,"text":124},{"id":190,"depth":519,"text":191},{"id":296,"depth":519,"text":297},{"id":324,"depth":519,"text":325},{"id":361,"depth":519,"text":362,"children":526},[527],{"id":448,"depth":516,"text":449},{"id":473,"depth":519,"text":474},"Sicherheitsgrundlagen","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcover-1200x630.png","Zwei gleiche Klappen in einer Wand, aus jeder ragt ein Blatt. Auf dem einen eine Reihe Schalter, auf dem anderen eine Spalte Gesichter.","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.",false,"md",[536,539,541,544,547],{"q":537,"a":538},"Was bedeutet \"offener API-Endpunkt\" in meinem Bericht?","Es bedeutet, dass wir den Code gelesen haben, den deine App an einen Browser schickt, darin eine Adresse gefunden haben, von der deine App Daten holt, und diese Adresse ohne Konto und ohne Login nach Daten gefragt haben. Sie hat geantwortet, und die Antwort war JSON. Das ist der ganze Befund. Er hält fest, was passiert ist, und urteilt nicht darüber, ob die Daten privat waren, denn das kann nichts außerhalb deiner App wissen.",{"q":47,"a":540},"Nein. Viele Adressen sollen jedem antworten: eine veröffentlichte Preisliste, ein Artikel, eine Liste der aktivierten Funktionen. Das Problem ist die Adresse, die Datensätze von Personen herausgibt, denn das tut sie für jeden, der die URL hat. Lies, was zurückkam, und frage dich, ob irgendetwas davon eine Person beschreibt.",{"q":542,"a":543},"Mein Bericht meldet einen Endpunkt, den ich nie geschrieben habe. Was ist das?","Meist einer deines Builders. Plattformen, die deiner App einen kleinen eigenen Server geben, legen auch ein paar eigene Adressen hinein, und die stecken im Code jeder App auf dieser Plattform. Das klarste Beispiel, das wir gemessen haben, sind die Cookie-Einstellungen von Base44 unter \u002Fapi\u002Fconsent\u002Fconfig, auf die 2.705 der 3.852 Befunde unseres Sweeps vom August 2026 entfallen. Sie geben Einstellungen zurück, sie sind auf jeder Base44-App gleich, und nichts darin gehört dir.",{"q":545,"a":546},"Wie prüfe ich, was die Endpunkte meiner App zurückgeben?","Öffne deine Live-App, drücke F12, klicke auf Netzwerk und lade neu. Die Anfragen, die als JSON zurückkommen, sind die Adressen, von denen deine App Daten holt. Kopiere jede URL, öffne ein privates Browserfenster, damit du abgemeldet bist, und füge sie einzeln ein. Lies, was ankommt. Ein Fehler oder eine leere Liste ist in Ordnung. Zeilen mit Namen, E-Mail-Adressen oder Bestellsummen kann jeder lesen, der diese Adresse hat.",{"q":548,"a":549},"Reicht es, den Pfad zu verstecken?","Nein. Die Adresse umzubenennen oder den Verweis darauf aus deinem Code zu nehmen, hält einen Scanner vom Finden ab und lässt sie genauso antworten wie vorher. Wer die URL schon hatte, hat sie weiterhin, und sie bleibt in Browser-Verläufen, Server-Logs und allem, was deine Seite gecrawlt hat. Behoben wird es an der Adresse: einen Login verlangen und einem Fremden mit einer 401 antworten.","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",[552,553,554,555,556,557,558],"offener api endpunkt","api endpunkt ohne authentifizierung","api endpunkt gibt daten ohne login zurück","ist mein api endpunkt öffentlich","ungeschützte api route","api endpunkt keine anmeldung","json endpunkt offen",{},true,"Ist ein offener API-Endpunkt ein Sicherheitsproblem?","\u002Fblog\u002Fopen-api-endpoint-exposed","2026-09-25",{"title":5,"description":532},"blog\u002Fopen-api-endpoint-exposed",[567,568,569],"Ein offener API-Endpunkt heißt: ein Pfad aus dem Code deiner App hat eine Anfrage ohne Login beantwortet, und zurück kam JSON.","Von denen, die wir über 30.926 Apps fanden, hatte sieben von zehn die Plattform hinterlegt, auf der die App veröffentlicht wurde, und sie geben Einstellungen zurück.","Entscheidend ist die Frage, ob irgendetwas in der Antwort eine Person beschreibt. Eine Preisliste ist absichtlich öffentlich. Eine Kundenliste war es nie.","aJ6NHTZC7P9laMU4Ghv4A97VQr7W6yVs_Xblfc3H8RQ",[572,578,584,590,596,602,608,614,620,626,632,638,644,651,657,663,668,669,675,681,687,693,699,705,711,717,723,729,735,741,747,753,759,765,771,777,783,789,795,801,807,813,819,825,831,837,843,848,854,860,866,872,878,884,889,895,901,906,911,917],{"path":573,"title":574,"description":575,"published":576,"category":529,"image":577,"draft":533},"\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":579,"title":580,"description":581,"published":582,"category":529,"image":583,"draft":533},"\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":585,"title":586,"description":587,"published":588,"category":529,"image":589,"draft":533},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" ohne RLS abzuschalten","\"Infinite recursion detected in policy for relation\" heißt: Deine Policy hat die Tabelle gefragt, die sie schützt. So brichst du den Kreis.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":591,"title":592,"description":593,"published":594,"category":529,"image":595,"draft":533},"\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":597,"title":598,"description":599,"published":600,"category":529,"image":601,"draft":533},"\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":603,"title":604,"description":605,"published":606,"category":529,"image":607,"draft":533},"\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":609,"title":610,"description":611,"published":612,"category":529,"image":613,"draft":533},"\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":615,"title":616,"description":617,"published":618,"category":529,"image":619,"draft":533},"\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":621,"title":622,"description":623,"published":624,"category":529,"image":625,"draft":533},"\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":627,"title":628,"description":629,"published":630,"category":529,"image":631,"draft":533},"\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":633,"title":634,"description":635,"published":636,"category":529,"image":637,"draft":533},"\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":639,"title":640,"description":641,"published":642,"category":529,"image":643,"draft":533},"\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":645,"title":646,"description":647,"published":648,"category":649,"image":650,"draft":533},"\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":652,"title":653,"description":654,"published":655,"category":649,"image":656,"draft":533},"\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":658,"title":659,"description":660,"published":661,"category":649,"image":662,"draft":533},"\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":664,"title":665,"description":666,"published":661,"category":529,"image":667,"draft":533},"\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":562,"title":5,"description":532,"published":563,"category":529,"image":550,"draft":533},{"path":670,"title":671,"description":672,"published":673,"category":529,"image":674,"draft":533},"\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":676,"title":677,"description":678,"published":679,"category":649,"image":680,"draft":533},"\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":682,"title":683,"description":684,"published":685,"category":529,"image":686,"draft":533},"\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":688,"title":689,"description":690,"published":691,"category":529,"image":692,"draft":533},"\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":694,"title":695,"description":696,"published":697,"category":529,"image":698,"draft":533},"\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":700,"title":701,"description":702,"published":703,"category":529,"image":704,"draft":533},"\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":706,"title":707,"description":708,"published":709,"category":529,"image":710,"draft":533},"\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":712,"title":713,"description":714,"published":715,"category":529,"image":716,"draft":533},"\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":718,"title":719,"description":720,"published":721,"category":529,"image":722,"draft":533},"\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":724,"title":725,"description":726,"published":727,"category":529,"image":728,"draft":533},"\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":730,"title":731,"description":732,"published":733,"category":649,"image":734,"draft":533},"\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":736,"title":737,"description":738,"published":739,"category":649,"image":740,"draft":533},"\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":742,"title":743,"description":744,"published":745,"category":649,"image":746,"draft":533},"\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":748,"title":749,"description":750,"published":751,"category":529,"image":752,"draft":533},"\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":754,"title":755,"description":756,"published":757,"category":529,"image":758,"draft":533},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","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":760,"title":761,"description":762,"published":763,"category":529,"image":764,"draft":533},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","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":766,"title":767,"description":768,"published":769,"category":529,"image":770,"draft":533},"\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":772,"title":773,"description":774,"published":775,"category":529,"image":776,"draft":533},"\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":778,"title":779,"description":780,"published":781,"category":529,"image":782,"draft":533},"\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":784,"title":785,"description":786,"published":787,"category":529,"image":788,"draft":533},"\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":790,"title":791,"description":792,"published":793,"category":529,"image":794,"draft":533},"\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":796,"title":797,"description":798,"published":799,"category":529,"image":800,"draft":533},"\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":802,"title":803,"description":804,"published":805,"category":529,"image":806,"draft":533},"\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":808,"title":809,"description":810,"published":811,"category":649,"image":812,"draft":533},"\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":814,"title":815,"description":816,"published":817,"category":529,"image":818,"draft":533},"\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":820,"title":821,"description":822,"published":823,"category":649,"image":824,"draft":533},"\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":826,"title":827,"description":828,"published":829,"category":529,"image":830,"draft":533},"\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":832,"title":833,"description":834,"published":835,"category":529,"image":836,"draft":533},"\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":838,"title":839,"description":840,"published":841,"category":529,"image":842,"draft":533},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","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":348,"title":844,"description":845,"published":846,"category":529,"image":847,"draft":533},"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":849,"title":850,"description":851,"published":852,"category":649,"image":853,"draft":533},"\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":855,"title":856,"description":857,"published":858,"category":649,"image":859,"draft":533},"\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":861,"title":862,"description":863,"published":864,"category":529,"image":865,"draft":533},"\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":867,"title":868,"description":869,"published":870,"category":529,"image":871,"draft":533},"\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":873,"title":874,"description":875,"published":876,"category":649,"image":877,"draft":533},"\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":879,"title":880,"description":881,"published":882,"category":529,"image":883,"draft":533},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","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":885,"title":886,"description":887,"published":882,"category":529,"image":888,"draft":533},"\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":890,"title":891,"description":892,"published":893,"category":529,"image":894,"draft":533},"\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":896,"title":897,"description":898,"published":899,"category":649,"image":900,"draft":533},"\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":291,"title":902,"description":903,"published":904,"category":529,"image":905,"draft":533},"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":907,"title":908,"description":909,"published":904,"category":649,"image":910,"draft":533},"\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":912,"title":913,"description":914,"published":915,"category":649,"image":916,"draft":533},"\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":512,"title":918,"description":919,"published":915,"category":529,"image":920,"draft":533},"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",1791618966337]