[{"data":1,"prerenderedAt":935},["ShallowReactive",2],{"blog-de-aws-access-key-exposed-in-frontend":3,"blog-index-de":406},{"id":4,"title":5,"body":6,"category":363,"cover":364,"coverAlt":365,"description":366,"draft":367,"extension":368,"faq":369,"image":383,"keywords":384,"meta":393,"navigation":394,"ogTitle":395,"path":396,"published":397,"seo":398,"stem":399,"tldr":400,"updated":397,"__hash__":405},"blog_de\u002Fblog\u002Faws-access-key-exposed-in-frontend.md","Ein offengelegter AWS-Schlüssel im Frontend ist kein OpenAI-Key",{"type":7,"value":8,"toc":350},"minimark",[9,18,21,26,39,45,59,65,69,72,79,85,91,97,100,104,107,110,116,119,128,132,135,138,141,150,155,159,162,171,198,209,217,221,224,227,238,241,245,251,260,280,290,307,310,314,337],[10,11,12,13,17],"p",{},"Jemand öffnet deine App im Browser, drückt F12 und findet eine Zeichenkette,\ndie mit ",[14,15,16],"code",{},"AKIA"," beginnt, mitten in deinem Frontend-Code. Oder GitHub schreibt\ndir, dass ein Commit vom vergangenen März AWS-Zugangsdaten enthält. Der Rat,\nder mit beidem kommt, ist immer derselbe: rotiere den Schlüssel. Bei den\nmeisten Schlüsseln ist das fast die ganze Antwort.",[10,19,20],{},"Hier ist der Teil, den eine Anleitung nach der anderen falsch macht. Ein im\nFrontend offengelegter AWS-Zugriffsschlüssel ist kein Schlüssel, der Geld\nausgibt. Er ist ein Schlüssel, der Dinge öffnet, und die beiden gehen in\nunterschiedliche Richtungen schief. Ein Schlüssel, der nur ausgibt, ist eine\nFirmenkarte: jemand macht eine Rechnung, du sperrst die Karte, und der Schaden\nist eine Zahl, die du auf einem Auszug lesen kannst. Ein Schlüssel, der Dinge\nöffnet, ist der Schlüsselbund zum Lager. Was er erreicht, hängt davon ab, was\nbeim Anfertigen daraufgeschrieben wurde, und das kannst du auf einem einzigen\nBildschirm in deiner AWS-Konsole nachlesen.",[22,23,25],"h2",{"id":24},"was-bedeutet-akia-am-anfang-eines-schlüssels","Was bedeutet AKIA am Anfang eines Schlüssels?",[10,27,28,29,31,32,35,36,38],{},"Es kennzeichnet einen langlebigen Zugriffsschlüssel, der entweder einem\nBenutzer in deinem Konto oder dem Root-Login des Kontos gehört. AWS schreibt\ndas Präfix in seiner eigenen Kennungsreferenz auf: ",[14,30,16],{}," für\nZugriffsschlüssel und ",[14,33,34],{},"ASIA"," für die temporären, die der Token-Dienst ausgibt.\nDie ersten vier Zeichen sagen dir also, welche Sorte du vor dir hast, und\n",[14,37,16],{}," ist die Sorte ohne Ablaufdatum. Er funktioniert, bis ihn jemand\nabschaltet.",[10,40,41,42,44],{},"AWS-Zugangsdaten sind zwei Zeichenketten, und eine Anfrage braucht beide, um\nsigniert zu werden. Die erste ist die Zugriffsschlüssel-Kennung, also der Teil,\nder mit ",[14,43,16],{}," beginnt. Die zweite ist der geheime Zugriffsschlüssel, eine\nlängere Zeichenkette ganz ohne Präfix davor. Die Kennung allein signiert\nnichts.",[10,46,47,48,50,51,54,55,58],{},"Das lohnt sich zu prüfen, bevor du entscheidest, wie schlimm dieser Morgen\nist, denn es ändert die Antwort. Wenn dein Bundle die ",[14,49,16],{},"-Zeichenkette trägt\nund nichts, was nach ihrer geheimen Hälfte aussieht, hat ein Besucher beim\nLesen deiner Seite den Namen des Schlüssels bekommen und nicht den Schlüssel.\nIn der Praxis reisen die beiden meist zusammen, denn was eines in den Browser\ngebracht hat, hat beide gebracht: ein Paar Umgebungsvariablen namens\n",[14,52,53],{},"AWS_ACCESS_KEY_ID"," und ",[14,56,57],{},"AWS_SECRET_ACCESS_KEY",", gelesen von Code, der auf\neinem Server hätte laufen sollen.",[60,61],"diagram",{"alt":62,"caption":63,"src":64},"Zwei Werte links übereinander: ein kurzer türkiser mit der Aufschrift AKIA und darunter ein längerer, dessen Inhalt als ausgeschwärzte Blöcke gezeichnet ist. Beide laufen in einen Pfeil zu einem Dokument mit Schlüsselsiegel zusammen, das abgehakt ist. Unter einer Trennlinie führt der AKIA-Wert allein zu einem Kreuz.","Beide Hälften zusammen signieren eine Anfrage. Die Kennung allein ist ein Name, und ein Name öffnet nichts.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Ftwo-strings-one-signature-1600x640.png",[22,66,68],{"id":67},"was-kann-jemand-mit-meinem-aws-zugriffsschlüssel-anfangen","Was kann jemand mit meinem AWS-Zugriffsschlüssel anfangen?",[10,70,71],{},"Was immer seine Berechtigungen erlauben, und nichts darüber hinaus. Es gibt\nalso drei Antworten.",[10,73,74,78],{},[75,76,77],"strong",{},"Was kann er lesen?"," Jeden S3-Bucket, den die Richtlinie aufführt, und jedes\nObjekt darin, auch die, auf die du nie von irgendwo verlinkt hast. Ein Bucket,\nden nichts in deiner App erwähnt, ist vor Zugangsdaten, die ihn auflisten\ndürfen, nicht verborgen.",[10,80,81,84],{},[75,82,83],{},"Was kann er schreiben?"," Dieselben Orte, und das ist die Hälfte, die man\nvergisst. Ein Schlüssel, der schreiben kann, kann auch überschreiben und\nlöschen, und eine an Ort und Stelle ersetzte Datei sieht genau aus wie die, die\ndu hochgeladen hast, bis sie jemand öffnet.",[10,86,87,90],{},[75,88,89],{},"Was kann er starten?"," Das ist die mit dem Zähler. Eine Richtlinie, die weit\ngenug für Rechenleistung ist, startet Rechenleistung, und die rechnet stündlich\nab, solange sie läuft. Nichts an der Browser-Kopie des Schlüssels begrenzt, wie\nviel von deinem Konto sie erreicht; die Richtlinie ist die einzige Grenze.",[10,92,93,94,96],{},"Die schlimmste Fassung davon ist ein Schlüssel, der für das Root-Login des\nKontos angefertigt wurde. AWS schreibt in seinen eigenen Hinweisen zum\nRoot-Benutzer, dass dieser uneingeschränkten Zugriff auf alle AWS-Dienste,\nRessourcen und Abrechnungsdaten hat, und rät davon ab, überhaupt\nZugriffsschlüssel dafür anzulegen. Wenn der Schlüssel auf deiner Seite mit\n",[14,95,16],{}," beginnt und dem Root-Benutzer gehört, ist das Offengelegte das ganze\nKonto und nicht ein Bucket.",[10,98,99],{},"Rate also bei nichts davon. Öffne IAM, finde den Benutzer, dem der Schlüssel\ngehört, und lies die Richtlinien an ihm. Das ist ein Bildschirm, und er\nbeantwortet alle drei Fragen oben.",[22,101,103],{"id":102},"reicht-es-ihn-einfach-zu-rotieren","Reicht es, ihn einfach zu rotieren?",[10,105,106],{},"Deaktiviere den offengelegten Schlüssel heute, und setze keinen Ersatz an\ndieselbe Stelle.",[10,108,109],{},"Deaktivieren ist der richtige erste Schritt und sanfter, als es klingt. AWS\nlässt einen Benutzer bis zu zwei aktive Zugriffsschlüssel gleichzeitig halten,\nund das gibt es genau dafür, dass ein Ersatz hochkommen kann, bevor der alte\nheruntergeht. Deaktivieren lässt den Schlüssel liegen und abgeschaltet, und er\nlässt sich wieder einschalten; Löschen ist unumkehrbar, und die geheime Hälfte\neines gelöschten Schlüssels ist nicht wiederherstellbar. Also deaktivieren,\nschauen, was kaputtgeht, und danach löschen.",[10,111,112,113,115],{},"Was das nicht abschließt, ist einen neuen Schlüssel anzulegen und ihn dorthin\nzu setzen, wo der alte war. Beim Leck ging es nie wirklich um diesen einen\nWert. Es ging darum, dass ein Browser Zugangsdaten ohne Ablaufdatum hält, und\nalles, was deine Seite herunterlädt, lädt jeder Besucher herunter. Eine frische\n",[14,114,16],{},"-Zeichenkette im selben Bundle kommt beim nächsten Scan als derselbe Fund\nzurück.",[10,117,118],{},"AWS sagt das klar in seinem Security Audit Guide, dort über mobile\nAnwendungen: sie sollten niemals eingebettete Zugriffsschlüssel enthalten, auch\nnicht verschlüsselt. Ein Browser-Bundle liest sich leichter als eine\nApp-Binärdatei, also gilt dieselbe Antwort hier und kostet einen Fremden\nweniger Arbeit.",[10,120,121,122,127],{},"Wenn du den Schlüssel bereits an einer öffentlichen Stelle gefunden hast, kommt\nes auf die Reihenfolge an, und\n",[123,124,126],"a",{"href":125},"\u002Fblog\u002Fapi-key-leaked-what-to-do","was zu tun ist, wenn ein API-Key geleakt wurde","\nlegt diese Reihenfolge für Schlüssel jeder Art hin.",[22,129,131],{"id":130},"was-eine-presigned-url-stattdessen-tut","Was eine presigned URL stattdessen tut",[10,133,134],{},"Sie lässt den Browser genau eine Sache mit genau einer Datei tun, ohne\nüberhaupt Zugangsdaten zu halten.",[10,136,137],{},"Dein eigener Server behält den Zugriffsschlüssel, wo ein Besucher ihn nicht\nlesen kann. Wenn deine Seite eine Datei in S3 legen oder eine herausholen muss,\nfragt sie deinen Server, und dein Server signiert eine URL für genau dieses\nObjekt und genau diese Aktion und reicht sie zurück. Der Browser benutzt die\nURL und bekommt nichts weiter dazu. AWS beschreibt eine presigned URL als\ntemporären Zugriff auf S3-Objekte ohne AWS-Zugangsdaten, und derselbe\nMechanismus deckt Downloads wie Uploads ab.",[10,139,140],{},"Zurück zum Lager. Eine presigned URL heißt, den Kurier an der Tür mit genau der\nKiste zu treffen, wegen der er gekommen ist, statt ihm den Schlüsselbund zu\ngeben und darauf zu vertrauen, dass er sie findet. Was der Kurier mitnimmt,\nhört auf zu funktionieren, wenn seine Uhr abgelaufen ist.",[10,142,143,144,146,147,149],{},"Für den Fall, dass jede angemeldete Person an ihre eigenen Dateien kommt,\nverweist AWS wieder woandershin: seine Hinweise zum Sichern von\nZugriffsschlüsseln sagen, mobile Anwendungen sollten Amazon Cognito für\nIdentitäten nutzen, statt Zugriffsschlüssel einzubetten. Was Cognito dem\nBrowser gibt, sind temporäre Zugangsdaten, die ",[14,145,34],{},"-Sorte vom Anfang dieses\nArtikels, die nach einer Weile von selbst aufhört zu funktionieren. Eine Kopie\ndavon, die am Dienstag von deiner Seite abgegriffen wird, ist am Mittwoch schon\ntot, und genau diese Eigenschaft hat ein ",[14,148,16],{},"-Schlüssel nicht.",[60,151],{"alt":152,"caption":153,"src":154},"Zwei Wege übereinander gezeichnet. Oben ein Browser mit einem Schlüssel daneben, ein Pfeil, und ein Regal mit acht Dateien auf zwei Böden. Unten derselbe Browser, ein Pfeil zu einem Server, der den Schlüssel hält, und ein Pfeil weiter zu einer einzelnen Datei mit einem Zifferblatt daneben.","Der obere Weg legt etwas in den Browser, das auf jede Datei wirkt, morgen genauso wie heute. Der untere gibt ihm eine Datei und eine Frist.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fkey-or-url-1600x700.png",[22,156,158],{"id":157},"wie-prüfe-ich-ob-meine-app-einen-aws-schlüssel-ausliefert","Wie prüfe ich, ob meine App einen AWS-Schlüssel ausliefert?",[10,160,161],{},"Durchsuche das, was der Browser heruntergeladen hat, nicht das, was in deinem\nProjekt liegt. Das sind zwei verschiedene Dateien, und es zählt die, die deine\nBesucher bekommen.",[10,163,164,167,168,170],{},[75,165,166],{},"Im Browser."," Öffne deine veröffentlichte Seite, drücke F12 und suche im\ngeladenen JavaScript nach ",[14,169,16],{},". Chrome und Edge durchsuchen aus dem\nSources-Panel alle geladenen Dateien auf einmal.",[10,172,173,176,177,179,180,182,183,185,186,54,189,192,193,197],{},[75,174,175],{},"In deinem Projekt."," Suche nach ",[14,178,16],{},", ",[14,181,53],{}," und\n",[14,184,57],{},". Suche dann nach den zwei Präfixen, die einen Wert\nabsichtlich ins Bundle legen, ",[14,187,188],{},"VITE_",[14,190,191],{},"NEXT_PUBLIC_",", und lies jeden Wert\ndahinter.\n",[123,194,196],{"href":195},"\u002Fblog\u002Fvite-and-next-public-env-vars","Warum diese zwei Präfixe alles veröffentlichen, was sie benennen",",\nist die Mechanik hinter den meisten davon, und es ist eine Regel des Builds,\ndie niemand versehentlich getippt hat.",[10,199,200,203,204,208],{},[75,201,202],{},"Von außen."," Unser kostenloser Scan liest deine veröffentlichte Seite so, wie\nein Fremder es täte, und meldet, welche Zugangsdaten er in dem sieht, was du\nausgeliefert hast, diese hier eingeschlossen. Er dauert etwa 20 Sekunden und\nbraucht kein Konto: ",[123,205,207],{"href":206},"\u002Fsecurity-scanner","App kostenlos scannen",".",[10,210,211,212,216],{},"Über alle Apps hinweg, die wir gescannt haben, ist das ein seltener Fund: ein\nAWS-Zugriffsschlüssel tauchte in 9 von 31.056 Apps auf, bei denen diese Prüfung\ndurchlief. Weit häufiger kommen Google-Schlüssel, die meist in Ordnung sind,\nund OpenAI-Schlüssel, die es meist nicht sind.\n",[123,213,215],{"href":214},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Was aus so gebauten Apps tatsächlich herausfließt","\nstellt sie alle mit den Zahlen nebeneinander.",[22,218,220],{"id":219},"was-der-schlüssel-getan-hat-während-er-draußen-war","Was der Schlüssel getan hat, während er draußen war",[10,222,223],{},"Öffne die CloudTrail-Ereignisliste und filtere sie nach der\nZugriffsschlüssel-Kennung.",[10,225,226],{},"Die Ereignisliste ist in jedem AWS-Konto an, ohne dass etwas eingeschaltet\nwerden muss, sie hält die letzten 90 Tage, und sie kostet nichts extra. Jeder\nEintrag trägt die Kennung des Schlüssels, der den Aufruf gemacht hat, du kannst\nalso nachlesen, was dein Schlüssel getan hat. Das beantwortet die Fragen zur\nKonfiguration: ein angelegter Bucket, eine geänderte Richtlinie, ein\nhinzugefügter Benutzer.",[10,228,229,230,233,234,237],{},"Dann gibt es den Teil, den man vorher wissen sollte. Die Ereignisliste hält\n",[75,231,232],{},"Management","-Ereignisse. Ein Objekt aus S3 zu lesen ist ein\n",[75,235,236],{},"Daten","-Ereignis, und AWS sagt ausdrücklich, dass Trails diese nicht\nstandardmäßig protokollieren und dass Datenereignisse gar nicht in der\nEreignisliste erscheinen. Sie einzuschalten zeichnet ab diesem Moment auf.",[10,239,240],{},"Die ehrliche Lesart ist also diese. Wenn der Schlüssel benutzt wurde, um dein\nKonto zu verändern, zeigt es dir das Protokoll. Wenn er benutzt wurde, um den\nInhalt eines Buckets herunterzuladen, zeigt es das wahrscheinlich nicht, und du\nentscheidest, was du deinen Kunden sagst, auf der Grundlage, dass es passiert\nsein kann.",[22,242,244],{"id":243},"wie-ein-schlüssel-aus-dem-nächsten-build-bleibt","Wie ein Schlüssel aus dem nächsten Build bleibt",[10,246,247,250],{},[75,248,249],{},"Zugangsdaten gehen zur Build-Zeit in den Browser, also ist der nächste Deploy\nder, auf den es zu achten gilt."," Der Schlüssel, den du heute herausnimmst, ist\nan dem Nachmittag wieder drin, an dem jemand eine Funktion mit S3 ergänzt und\neinen Agenten bittet, sie zu verdrahten.",[10,252,253],{},[75,254,255,259],{},[123,256,258],{"href":257},"\u002Fwebsite-monitoring","Reeve Monitor"," liest deine veröffentlichte Seite für dich erneut:",[261,262,263,267,274,277],"ul",{},[264,265,266],"li",{},"alle neun Prüfungen jede Stunde, für bis zu drei Apps",[264,268,269,270,273],{},"eine Nachricht, wenn sich ein Ergebnis ",[75,271,272],{},"ändert",", damit ein Schlüssel, der am Dienstag auftaucht, nicht wartet, bis du das nächste Mal nachsiehst",[264,275,276],{},"ob die App erreichbar ist, alle 60 Sekunden",[264,278,279],{},"ein monatlicher Bericht über das Gesehene",[10,281,282],{},[75,283,284,285,289],{},"Wenn deine App ihre Daten in einem Supabase-Projekt hält, bewahrt\n",[123,286,288],{"href":287},"\u002Fsupabase-backups","Reeve Care"," davon ebenfalls eine Kopie:",[261,291,292,295,298,301,304],{},[264,293,294],{},"eine verschlüsselte Kopie deiner Supabase-Datenbank jede Nacht, dort abgelegt, wo dein Projekt sie nicht erreicht",[264,296,297],{},"jede Kopie geprüft, bevor sie zählt, durch Zählen der Zeilen in jeder Tabelle",[264,299,300],{},"eine Wiederherstellung mit einem Klick, wenn du sie brauchst",[264,302,303],{},"auch deine hochgeladenen Dateien, sobald du Storage-Zugangsdaten verbindest",[264,305,306],{},"alles, was Monitor tut",[10,308,309],{},"Jede dieser neun Prüfungen beschreibt, was ein Fremder erreichen kann. Eine\nKopie der Datenbank von gestern Nacht beantwortet die andere Frage, nämlich\nwas jemand bereits verändert hat, während der Schlüssel draußen war.",[22,311,313],{"id":312},"was-diese-woche-zu-tun-ist","Was diese Woche zu tun ist",[315,316,317],"key-takeaways",{},[261,318,319,325,328,331,334],{},[264,320,321,322,324],{},"Öffne deine veröffentlichte Seite, drücke F12 und suche im geladenen JavaScript nach ",[14,323,16],{},". Das ist die Datei, die deine Besucher haben, und nur die zählt.",[264,326,327],{},"Wenn du einen findest, deaktiviere ihn heute in IAM. Deaktivieren ist umkehrbar und wirkt sofort; Löschen ist es nicht, und die geheime Hälfte lässt sich nicht wiederherstellen.",[264,329,330],{},"Lies die Richtlinien am Benutzer des Schlüssels, bevor du entscheidest, wie ernst das ist. Was er lesen, was er schreiben und was er starten kann, sind drei getrennte Antworten.",[264,332,333],{},"Ersetze das Muster statt des Werts. Dein Server hält den Schlüssel und signiert eine presigned URL für ein Objekt, oder Amazon Cognito gibt dem Browser temporäre Zugangsdaten, die von selbst ablaufen.",[264,335,336],{},"Filtere die CloudTrail-Ereignisliste für die letzten 90 Tage nach dem Schlüssel. Sie zeigt dir, was der Schlüssel konfiguriert hat, und sie zeigt dir nicht, welche Dateien er gelesen hat, sofern Datenereignisse nicht schon eingeschaltet waren.",[10,338,339,340,344,345,349],{},"Fang mit der F12-Suche an, denn sie klärt in einer Minute, ob du überhaupt ein\nProblem hast. Wenn sie etwas zutage fördert, deckt die\n",[123,341,343],{"href":342},"\u002Fchecklist","Sicherheits-Checkliste in 10 Minuten"," den Rest dessen ab, was eine\nfrisch gestartete App gern offen lässt, und\n",[123,346,348],{"href":347},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","ein Geheimnis in eine Edge Function verschieben","\nist das Muster für jeden Schlüssel, der nie auf der Seite hätte sein sollen.",{"title":351,"searchDepth":352,"depth":352,"links":353},"",3,[354,356,357,358,359,360,361,362],{"id":24,"depth":355,"text":25},2,{"id":67,"depth":355,"text":68},{"id":102,"depth":355,"text":103},{"id":130,"depth":355,"text":131},{"id":157,"depth":355,"text":158},{"id":219,"depth":355,"text":220},{"id":243,"depth":355,"text":244},{"id":312,"depth":355,"text":313},"Sicherheitsgrundlagen","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcover-1200x630.png","Eine Seite App-Code mit einem kurzen hellen Wert und einem langen verdeckten darunter, ein Schlüssel über ihrer Ecke, dahinter ein Regal voller Dateien.","Ein im Frontend offengelegter AWS-Zugriffsschlüssel liest und schreibt deinen Speicher. Die Lösung ist meist eine presigned URL, kein neuer Schlüssel.",false,"md",[370,373,375,378,380],{"q":371,"a":372},"Sind AWS-Schlüssel im Frontend-Code jemals in Ordnung?","Nein. AWS sagt das in seinem eigenen Security Audit Guide über mobile Apps: Anwendungen sollten niemals eingebettete Zugriffsschlüssel enthalten, auch nicht verschlüsselt. Ein Browser-Bundle liest sich leichter als eine App-Binärdatei, also gilt dieselbe Antwort hier und kostet einen Fremden weniger Arbeit. Wenn deine Seite wirklich S3 erreichen muss, sind die vorgesehenen Wege eine presigned URL, die dein eigener Server signiert, oder temporäre Zugangsdaten von Amazon Cognito, die von selbst ablaufen.",{"q":68,"a":374},"Genau das, was die Berechtigungen dahinter erlauben, weshalb es keine einzelne Antwort gibt. Ein Schlüssel an einem Benutzer mit Lesezugriff auf einen Bucket liest diesen Bucket. Ein Schlüssel an einem Administrator tut alles, was ein Administrator tut, einschließlich Maschinen zu starten, die stündlich abrechnen. Ein Schlüssel des Root-Benutzers des Kontos ist der schlimmste Fall, denn AWS schreibt, dass der Root-Benutzer uneingeschränkten Zugriff auf alle Dienste, Ressourcen und Abrechnungsdaten hat. Öffne IAM und lies die Richtlinien am Schlüssel, bevor du entscheidest, wie besorgt du sein musst.",{"q":376,"a":377},"Was ist eine presigned URL?","Eine lange URL, mit der ein Browser genau eine Sache mit genau einer Datei in S3 tun darf, für eine festgelegte Anzahl Sekunden, ohne irgendwelche AWS-Zugangsdaten zu halten. Dein eigener Server hält den Schlüssel und signiert die URL auf Anfrage. AWS beschreibt presigned URLs als temporären Zugriff auf S3-Objekte ohne AWS-Zugangsdaten, und sie funktionieren für Downloads wie für Uploads.",{"q":158,"a":379},"Durchsuche das, was dein Browser heruntergeladen hat, und nicht das, was in deinem Projekt liegt. Öffne deine veröffentlichte Seite, drücke F12 und suche im geladenen JavaScript nach AKIA. Durchsuche dann dein Projekt nach AKIA, AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY und nach jedem Variablennamen, der mit VITE_ oder NEXT_PUBLIC_ beginnt und so etwas hält, denn diese Präfixe sind es, die einen Wert überhaupt erst ins Bundle legen.",{"q":381,"a":382},"Mein AWS-Schlüssel liegt auf GitHub. Was jetzt?","Deaktiviere ihn zuerst in IAM, das ist umkehrbar und wirkt sofort, und lege dann einen Ersatz für den Server an, der ihn gebraucht hat. Ihn aus dem Code zu löschen schließt nichts, denn der alte Wert bleibt in deiner Commit-Historie und in jedem Klon, den jemand gezogen hat. Öffne danach die CloudTrail-Ereignisliste und filtere nach dem Schlüssel, um zu sehen, was er getan hat.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",[385,386,387,388,389,390,391,392],"aws zugriffsschlüssel im frontend offengelegt","aws key im frontend","aws access key geleakt","akia schlüssel offengelegt","aws secret access key in javascript","aws zugangsdaten im clientcode","sind aws keys in react sicher","aws key auf github",{},true,"AWS-Zugriffsschlüssel im Frontend offengelegt?","\u002Fblog\u002Faws-access-key-exposed-in-frontend","2026-10-12",{"title":5,"description":366},"blog\u002Faws-access-key-exposed-in-frontend",[401,402,403,404],"Ein im Frontend offengelegter AWS-Zugriffsschlüssel ist ein anderes Problem als ein Schlüssel, der nur Geld ausgeben kann. Was er erreicht, entscheiden seine Berechtigungen.","Zwei Zeichenketten signieren eine AWS-Anfrage: eine Kennung, die mit `AKIA` beginnt, und eine geheime Hälfte. Eine ohne die andere signiert nichts.","Ein neuer Schlüssel an derselben Stelle ist derselbe Fund mit einem anderen Wert. Die Lösung ist eine presigned URL, damit der Browser überhaupt keine Zugangsdaten hält.","Wir haben einen in 9 von 31.056 gescannten Apps gefunden, bei denen diese Prüfung durchlief.","SiSah3n5rHTokhyXmxujeLrayI2ZdpXA0zWBvmFnyYg",[407,413,419,425,431,437,443,449,455,461,467,474,480,486,492,498,504,510,516,522,528,534,540,546,552,558,564,570,576,577,583,589,594,600,606,612,617,623,629,635,641,647,653,659,665,671,676,682,688,694,700,706,712,718,723,729,735,741,747,753,759,765,771,777,783,789,795,801,807,813,818,824,830,836,842,848,854,860,866,872,878,884,890,896,901,907,913,919,924,930],{"path":408,"title":409,"description":410,"published":411,"category":363,"image":412,"draft":367},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\" erklärt","Supabase \"max client connections reached\": Der Pooler hat keinen Platz für noch einen Client. Der Port in deinem Connection String setzt das Limit.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":414,"title":415,"description":416,"published":417,"category":363,"image":418,"draft":367},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Supabase-Fehler: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\" heißt: Google-Login ist in deinem Supabase-Projekt aus. Die Lösung, und was bei redirect_uri_mismatch hilft.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":420,"title":421,"description":422,"published":423,"category":363,"image":424,"draft":367},"\u002Fblog\u002Fviolates-foreign-key-constraint","Supabase-Fehler \"violates foreign key constraint\" beim Einfügen","Supabase \"insert or update on table violates foreign key constraint\": Deine Zeile zeigt auf eine, die es nicht gibt. Welche, warum, und die Lösung.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":426,"title":427,"description":428,"published":429,"category":363,"image":430,"draft":367},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Supabase-Fehler \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": Eine Pflichtspalte kam leer an. Woher die Null kommt, und die Lösung.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":432,"title":433,"description":434,"published":435,"category":363,"image":436,"draft":367},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": wo die Sitzung geblieben ist","\"Auth session missing!\" heißt: supabase-js fand keine angemeldete Sitzung und fragte Supabase gar nicht erst. Wo die Sitzung blieb, und die Lösung je Fall.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":438,"title":439,"description":440,"published":441,"category":363,"image":442,"draft":367},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": niemand ist angemeldet","\"invalid claim: missing sub claim\" heißt: Supabase Auth bekam ein echtes Token ohne Nutzer darin, deinen Projektschlüssel statt einer Sitzung.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":444,"title":445,"description":446,"published":447,"category":363,"image":448,"draft":367},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": der echte Grund","\"Failed to send a request to the Edge Function\" heißt: Der Browser hat keine lesbare Antwort bekommen. Seine Konsole sagt, warum, und ob deine Funktion lief.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":450,"title":451,"description":452,"published":453,"category":363,"image":454,"draft":367},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Warum Supabase-E-Mail-Links auf localhost:3000 weiterleiten","Leitet Supabase auf localhost:3000 um, ist die Site URL unverändert, oder deine Adresse fehlt in Redirect URLs. Die Lösung und der Platzhalter, den du meidest.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":456,"title":457,"description":458,"published":459,"category":363,"image":460,"draft":367},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" bei einem neuen Link","Bei einem Link von vor einer Minute heißt Supabases \"Email link is invalid or has expired\" meist: Ein Mailfilter hat ihn zuerst benutzt. Prüfen und beheben.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":462,"title":463,"description":464,"published":465,"category":363,"image":466,"draft":367},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\" erklärt","Supabase \"canceling statement due to statement timeout\": Eine Abfrage lief länger als ihre Rolle darf, 3 Sekunden für Besucher. Prüf zuerst die RLS-Regel.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":468,"title":469,"description":470,"published":471,"category":472,"image":473,"draft":367},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" in Supabase und was mitgelöscht wird","\"Database error deleting user\" in Supabase heißt: Deine Datenbank hat das Löschen abgelehnt. Der Grund steht im Log, die Lösung entscheidet, was mitgeht.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":475,"title":476,"description":477,"published":478,"category":363,"image":479,"draft":367},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" bei Supabase","Ein Stripe-Webhook in einer Supabase Edge Function meldet \"No signatures found matching the expected signature\"? Zwei Ursachen. Prüfe weiter.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":481,"title":482,"description":483,"published":484,"category":363,"image":485,"draft":367},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" in Supabase: die drei Ursachen","Supabase sagt \"Invalid login credentials\" bei falschem Passwort, unbekannter E-Mail und Google-Konto. So erkennst du, welcher Fall es ist.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":487,"title":488,"description":489,"published":490,"category":363,"image":491,"draft":367},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": der echte Fehler","\"Edge Function returned a non-2xx status code\" heißt: Deine Supabase-Funktion hat mit einem Fehler geantwortet. So liest du den echten.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":493,"title":494,"description":495,"published":496,"category":363,"image":497,"draft":367},"\u002Fblog\u002Fcertificate-not-trusted","Zertifikat nicht vertrauenswürdig: drei Ursachen außer Ablauf","Zertifikat nicht vertrauenswürdig, obwohl das Datum stimmt? Es nennt eine andere Adresse, hat sich selbst signiert oder seiner Kette fehlt ein Glied.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":499,"title":500,"description":501,"published":502,"category":363,"image":503,"draft":367},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": was im Zitat steht","Supabase \"invalid input syntax for type uuid\" heißt: Deine App hat etwas geschickt, das keine ID ist. Zitat lesen, Abfrage zurückhalten, Spalte behalten.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":505,"title":506,"description":507,"published":508,"category":363,"image":509,"draft":367},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\" erklärt","Supabase \"duplicate key value violates unique constraint\" heißt: Der Wert ist schon vergeben. Spalte finden, Lösung wählen, Wert vom Bildschirm fernhalten.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":511,"title":512,"description":513,"published":514,"category":363,"image":515,"draft":367},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\", obwohl die Tabelle da ist","Supabase \"relation does not exist\" oder PGRST205: Keine Tabelle passt zu Name und Schema deiner Abfrage. Vier Prüfungen, und was eine Freigabe öffnet.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":517,"title":518,"description":519,"published":520,"category":363,"image":521,"draft":367},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" nennt die Argumente, die deine App geschickt hat. Vergleich sie mit der Funktion.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":523,"title":524,"description":525,"published":526,"category":363,"image":527,"draft":367},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" heißt meist: Der Name passt nicht. Vier Prüfungen und der Einzeiler zum Neuladen.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":529,"title":530,"description":531,"published":532,"category":363,"image":533,"draft":367},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": zwei Limits, ein Fehlercode","Supabase \"Email Rate Limit Exceeded\" begrenzt jede E-Mail deines Projekts: 2 pro Stunde beim eingebauten Absender. Was zählt und wie du es anhebst.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":535,"title":536,"description":537,"published":538,"category":363,"image":539,"draft":367},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 Ursachen","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" meldet deine Nutzer ab. Drei Ursachen, und wie das Auth-Log sie trennt.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":541,"title":542,"description":543,"published":544,"category":363,"image":545,"draft":367},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": drei Ursachen","Supabase \"permission denied for schema public\" heißt: Ein Grant auf das Schema fehlt. Was ihn entfernt hat und welche Zeile ihn zurückbringt.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":547,"title":548,"description":549,"published":550,"category":363,"image":551,"draft":367},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": die drei Dinge, die es bedeutet","Supabase \"Bucket not found\" ist eins von drei Dingen: ein öffentlicher Link zu einem privaten Bucket, ein ungenauer Name oder das falsche Projekt.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":553,"title":554,"description":555,"published":556,"category":363,"image":557,"draft":367},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: Welcher Schlüssel streikt hier?","Ein Supabase invalid JWT ist PGRST301: ein signiertes Token hat die Prüfung nicht bestanden. In neueren Projekten ist das die Sitzung, nicht der API-Schlüssel.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":559,"title":560,"description":561,"published":562,"category":363,"image":563,"draft":367},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" heißt meist: keine Zeilen","Supabase gibt PGRST116 zurück, \"JSON object requested, multiple (or no) rows returned\", wenn die Abfrage nichts fand. Versteckte Zeilen wirken fehlend.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":565,"title":566,"description":567,"published":568,"category":363,"image":569,"draft":367},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" in Supabase: wo du nachsiehst","\"Database error saving new user\" heißt: etwas an deiner Supabase-Registrierung ist fehlgeschlagen. Der echte Fehler steht in deinen Logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":571,"title":572,"description":573,"published":574,"category":363,"image":575,"draft":367},"\u002Fblog\u002Fwhat-is-supabase","Was ist Supabase? Die Datenbank, die dein Builder ausgesucht hat","Was ist Supabase: die Datenbank, der Login und der Dateispeicher hinter deiner App. Supabase betreibt die Server, die Regeln zu deinen Zeilen gehören dir.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":396,"title":5,"description":366,"published":397,"category":363,"image":383,"draft":367},{"path":578,"title":579,"description":580,"published":581,"category":363,"image":582,"draft":367},"\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":584,"title":585,"description":586,"published":587,"category":363,"image":588,"draft":367},"\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":125,"title":590,"description":591,"published":592,"category":363,"image":593,"draft":367},"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":595,"title":596,"description":597,"published":598,"category":363,"image":599,"draft":367},"\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":601,"title":602,"description":603,"published":604,"category":363,"image":605,"draft":367},"\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":607,"title":608,"description":609,"published":610,"category":363,"image":611,"draft":367},"\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":347,"title":613,"description":614,"published":615,"category":363,"image":616,"draft":367},"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":618,"title":619,"description":620,"published":621,"category":363,"image":622,"draft":367},"\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":624,"title":625,"description":626,"published":627,"category":363,"image":628,"draft":367},"\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":630,"title":631,"description":632,"published":633,"category":363,"image":634,"draft":367},"\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":636,"title":637,"description":638,"published":639,"category":363,"image":640,"draft":367},"\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":642,"title":643,"description":644,"published":645,"category":363,"image":646,"draft":367},"\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":648,"title":649,"description":650,"published":651,"category":363,"image":652,"draft":367},"\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":654,"title":655,"description":656,"published":657,"category":472,"image":658,"draft":367},"\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","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":660,"title":661,"description":662,"published":663,"category":472,"image":664,"draft":367},"\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":666,"title":667,"description":668,"published":669,"category":472,"image":670,"draft":367},"\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":672,"title":673,"description":674,"published":669,"category":363,"image":675,"draft":367},"\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":677,"title":678,"description":679,"published":680,"category":363,"image":681,"draft":367},"\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":683,"title":684,"description":685,"published":686,"category":363,"image":687,"draft":367},"\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":689,"title":690,"description":691,"published":692,"category":472,"image":693,"draft":367},"\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":695,"title":696,"description":697,"published":698,"category":363,"image":699,"draft":367},"\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":701,"title":702,"description":703,"published":704,"category":363,"image":705,"draft":367},"\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":707,"title":708,"description":709,"published":710,"category":363,"image":711,"draft":367},"\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":713,"title":714,"description":715,"published":716,"category":363,"image":717,"draft":367},"\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":195,"title":719,"description":720,"published":721,"category":363,"image":722,"draft":367},"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":724,"title":725,"description":726,"published":727,"category":363,"image":728,"draft":367},"\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":730,"title":731,"description":732,"published":733,"category":363,"image":734,"draft":367},"\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":736,"title":737,"description":738,"published":739,"category":363,"image":740,"draft":367},"\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":742,"title":743,"description":744,"published":745,"category":472,"image":746,"draft":367},"\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":748,"title":749,"description":750,"published":751,"category":472,"image":752,"draft":367},"\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":754,"title":755,"description":756,"published":757,"category":472,"image":758,"draft":367},"\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":760,"title":761,"description":762,"published":763,"category":363,"image":764,"draft":367},"\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":766,"title":767,"description":768,"published":769,"category":363,"image":770,"draft":367},"\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":772,"title":773,"description":774,"published":775,"category":363,"image":776,"draft":367},"\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":778,"title":779,"description":780,"published":781,"category":363,"image":782,"draft":367},"\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":784,"title":785,"description":786,"published":787,"category":363,"image":788,"draft":367},"\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. Acht Tools im Vergleich, mit Preisen und unseren Lücken.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":790,"title":791,"description":792,"published":793,"category":363,"image":794,"draft":367},"\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":796,"title":797,"description":798,"published":799,"category":363,"image":800,"draft":367},"\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":802,"title":803,"description":804,"published":805,"category":363,"image":806,"draft":367},"\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":808,"title":809,"description":810,"published":811,"category":363,"image":812,"draft":367},"\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":214,"title":814,"description":815,"published":816,"category":363,"image":817,"draft":367},"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":819,"title":820,"description":821,"published":822,"category":472,"image":823,"draft":367},"\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":825,"title":826,"description":827,"published":828,"category":363,"image":829,"draft":367},"\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":831,"title":832,"description":833,"published":834,"category":472,"image":835,"draft":367},"\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":837,"title":838,"description":839,"published":840,"category":363,"image":841,"draft":367},"\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":843,"title":844,"description":845,"published":846,"category":363,"image":847,"draft":367},"\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":849,"title":850,"description":851,"published":852,"category":363,"image":853,"draft":367},"\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":855,"title":856,"description":857,"published":858,"category":363,"image":859,"draft":367},"\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":861,"title":862,"description":863,"published":864,"category":472,"image":865,"draft":367},"\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":867,"title":868,"description":869,"published":870,"category":472,"image":871,"draft":367},"\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":873,"title":874,"description":875,"published":876,"category":363,"image":877,"draft":367},"\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":879,"title":880,"description":881,"published":882,"category":363,"image":883,"draft":367},"\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":885,"title":886,"description":887,"published":888,"category":472,"image":889,"draft":367},"\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":891,"title":892,"description":893,"published":894,"category":363,"image":895,"draft":367},"\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":897,"title":898,"description":899,"published":894,"category":363,"image":900,"draft":367},"\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":902,"title":903,"description":904,"published":905,"category":363,"image":906,"draft":367},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: ist er derselbe wie der anon key?","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":908,"title":909,"description":910,"published":911,"category":472,"image":912,"draft":367},"\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":914,"title":915,"description":916,"published":917,"category":363,"image":918,"draft":367},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security ist an. Die Tabelle ist trotzdem offen.","Supabase Row Level Security anzuschalten schützt keine Tabelle. Erst deine Policies tun das, und die, die deine App repariert hat, lässt oft alle herein.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":920,"title":921,"description":922,"published":917,"category":472,"image":923,"draft":367},"\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":925,"title":926,"description":927,"published":928,"category":472,"image":929,"draft":367},"\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":931,"title":932,"description":933,"published":928,"category":363,"image":934,"draft":367},"\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",1794213638796]