[{"data":1,"prerenderedAt":662},["ShallowReactive",2],{"blog-pt-what-secrets-leak-from-vibe-coded-apps":3,"blog-index-pt":421},{"id":4,"title":5,"body":6,"category":380,"cover":381,"coverAlt":382,"description":383,"draft":384,"extension":385,"faq":386,"image":402,"keywords":403,"meta":409,"navigation":410,"ogTitle":411,"path":412,"published":413,"seo":414,"stem":415,"tldr":416,"updated":413,"__hash__":420},"blog_pt\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps.md","Chave de API exposta no frontend: o que 30.998 apps entregam",{"type":7,"value":8,"toc":368},"minimark",[9,13,16,21,24,33,45,49,52,59,69,75,86,90,93,180,183,189,200,208,212,218,237,242,248,252,255,269,277,281,299,308,311,326,330,356],[10,11,12],"p",{},"Alguém abre seu app, aperta F12 e diz que existe uma chave de API exposta no seu\nfrontend. A palavra usada costuma ser \"vazou\". Raramente dizem qual chave é, e os\nconselhos que você encontra depois tratam todas como a mesma emergência.",[10,14,15],{},"Não são a mesma emergência, e agora conseguimos colocar números nessa distância.\nEntre 12 e 14 de agosto de 2026 rodamos nove verificações externas em 30.998 apps\nno ar criados com Lovable, Bolt, v0, Replit e Base44, e lemos o JavaScript que\ncada um entrega a um navegador. Foi isto que havia dentro.",[17,18,20],"h2",{"id":19},"uma-chave-de-api-exposta-no-frontend-é-mesmo-um-problema","Uma chave de API exposta no frontend é mesmo um problema?",[10,22,23],{},"Quase nunca, e o formato desse \"quase nunca\" é mais desequilibrado do que\nesperávamos.",[10,25,26,27,32],{},"Encontramos uma chave digna de nota em 1.332 dos 30.998 apps. Em 1.080 deles, a\núnica coisa que achamos foi uma chave de API do Google, que é exatamente a\ncredencial ",[28,29,31],"a",{"href":30},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","que deve estar na sua página",".\nO que protege essa é uma configuração guardada do lado do Google, e escondê-la\nnunca fez parte do combinado.",[10,34,35,36,40,41,44],{},"Os outros 29.666 apps não entregavam nada que nossa verificação de segredos trate\ncomo problema. Esse número precisa de uma ressalva para ser honesto: as chaves\npublicáveis ficam de fora. Uma chave ",[37,38,39],"code",{},"anon"," do Supabase ou uma chave ",[37,42,43],{},"pk_"," do\nStripe pertence ao navegador, então a marcamos como algo que você fez certo e ela\nnunca entra nessas contagens.",[17,46,48],{"id":47},"o-que-contamos-e-o-que-não-conseguimos-contar","O que contamos e o que não conseguimos contar",[10,50,51],{},"Carregamos cada app do jeito que um visitante carrega, num navegador de verdade,\ne lemos o JavaScript baixado. Tudo o que vem a seguir é uma forma encontrada\nnesse código.",[10,53,54,58],{},[55,56,57],"strong",{},"Reconhecemos os formatos de chave que conhecemos."," Stripe, OpenAI, Anthropic,\nAWS, Google e Supabase têm prefixos identificáveis, e um JWT do Supabase declara\no próprio papel em texto legível na seção do meio. Uma credencial num formato que\nnão reconhecemos não está nestes números, então leia-os como um piso.",[10,60,61,64,65,68],{},[55,62,63],{},"Não usamos nenhuma chave que encontramos."," Nenhuma vez, em nenhum app.\nRegistramos o tipo e uma dica mascarada no formato ",[37,66,67],{},"sk_live_…a1b2",", e o valor\nreal não foi escrito em lugar nenhum.",[10,70,71,74],{},[55,72,73],{},"Nenhum app é nomeado."," Nem aqui, nem no conjunto de dados, nem em nada que\npublicamos.",[10,76,77,80,81,85],{},[55,78,79],{},"Quase todos são apps publicados no domínio do próprio builder."," O método\ncompleto, a amostra e cada número por trás deste artigo estão no\n",[28,82,84],{"href":83},"\u002Fresearch\u002Fvibe-coded-app-security-2026","nosso relatório de varredura",", incluindo\no que não conseguimos medir.",[17,87,89],{"id":88},"o-que-os-30998-apps-entregavam-de-verdade","O que os 30.998 apps entregavam de verdade",[10,91,92],{},"Uma tabela, ordenada pela frequência com que vimos cada coisa. A verificação de\nsegredos foi concluída em todos os 30.998 apps, então cada contagem abaixo é\nsobre todos eles.",[94,95,96,109],"table",{},[97,98,99],"thead",{},[100,101,102,106],"tr",{},[103,104,105],"th",{},"O que encontramos no código do navegador",[103,107,108],{},"Apps",[110,111,112,121,129,137,145,153,165,172],"tbody",{},[100,113,114,118],{},[115,116,117],"td",{},"Chave de API do Google",[115,119,120],{},"1.142",[100,122,123,126],{},[115,124,125],{},"Um valor de alta entropia ao lado de um nome \"secret\" ou \"password\"",[115,127,128],{},"204",[100,130,131,134],{},[115,132,133],{},"Chave da OpenAI",[115,135,136],{},"33",[100,138,139,142],{},[115,140,141],{},"Chave de acesso da AWS",[115,143,144],{},"9",[100,146,147,150],{},[115,148,149],{},"Chave da Anthropic",[115,151,152],{},"5",[100,154,155,162],{},[115,156,157,158,161],{},"Chave ",[37,159,160],{},"service_role"," do Supabase",[115,163,164],{},"3",[100,166,167,170],{},[115,168,169],{},"Chave secreta do Stripe",[115,171,164],{},[100,173,174,177],{},[115,175,176],{},"Chave restrita do Stripe",[115,178,179],{},"2",[10,181,182],{},"As linhas somam mais de 1.332 porque um app pode carregar duas delas. Separe\nesses mesmos 1.332 apps em grupos que não se sobrepõem e o quadro fica ainda mais\nnítido: 1.080 tinham uma chave do Google e nada mais, 198 tinham um valor de alta\nentropia que pode ou não ser uma credencial real, e 54 tinham uma chave que é um\nsegredo genuíno pela própria forma.",[184,185],"diagram",{"alt":186,"caption":187,"src":188},"Uma única barra larga representando os 1.332 apps em que uma chave foi encontrada, dividida em três partes: uma seção turquesa longa de 1.080, uma seção âmbar mais curta de 198 e uma estreita seção vermelha de 54 na ponta direita.","Cada app em que encontramos alguma chave, separado em três grupos que não se sobrepõem. A seção vermelha é a de que falam os avisos.","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fwhat-we-found-1600x620.png",[10,190,191,192,195,196,199],{},"O segundo grupo merece ser descrito com cuidado. Um valor de alta entropia ao\nlado de uma palavra como ",[37,193,194],{},"secret"," ou ",[37,197,198],{},"password"," pode ser uma credencial viva, ou\npode ser um identificador de sessão, um hash de build ou um token público com um\nnome infeliz. Sinalizamos como algo que vale olhar, e de fora ninguém consegue\ndizer qual desses é.",[10,201,202,203,207],{},"Os 54 do terceiro grupo são a coisa real. Todos menos dois saíram com nota D ou\nF, porque um único achado crítico limita a nota a D por melhor que o app tenha\nfeito o resto. O maior grupo isolado dentro deles é a chave da OpenAI, com 33, e\nessa\n",[28,204,206],{"href":205},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","não tem nenhuma configuração que a torne segura num navegador",".",[17,209,211],{"id":210},"a-chave-contra-a-qual-todos-avisam-foi-a-coisa-mais-rara-que-encontramos","A chave contra a qual todos avisam foi a coisa mais rara que encontramos",[10,213,214,215,217],{},"Três apps. Foi essa a quantidade que entregava uma chave ",[37,216,160],{}," do\nSupabase, a que passa por cima de cada regra de tabela que você escreveu. Uma\nchave secreta do Stripe também apareceu três vezes.",[10,219,220,221,223,224,227,228,227,231,227,234,207],{},"Coloque isso ao lado da outra metade da mesma varredura. Dos apps que escaneamos,\n8.429 nomeavam um projeto Supabase, e os dois achados ficam dentro desse mesmo\ngrupo. Três deles entregavam a chave ",[37,222,160],{},". Em 2.096 deles, ao menos uma\ntabela respondeu a uma requisição sem login nenhum, e em 394 essa tabela tinha\nnome de pessoas: ",[37,225,226],{},"users",", ",[37,229,230],{},"profiles",[37,232,233],{},"customers",[37,235,236],{},"orders",[184,238],{"alt":239,"caption":240,"src":241},"Duas linhas desenhadas na mesma escala. A linha de cima, marcada com uma chave, é uma faixa vermelha tão fina que precisa de um anel tracejado para ser vista, rotulada com 3. A linha de baixo, marcada com uma tabela, é uma faixa turquesa que ocupa quase toda a largura, rotulada com 2.096.","As duas contagens vêm dos mesmos 8.429 apps com Supabase. A linha de cima é o achado contra o qual os donos são avisados.","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fwarned-about-vs-found-1600x680.png",[10,243,244,245,247],{},"Os 2.096 são um piso. 4.749 dos 8.429 nunca responderam à nossa verificação de\nbanco de dados, por motivos que não vemos de fora, e esses ficam registrados como\ndesconhecidos em vez de limpos. As três chaves ",[37,246,160],{}," são uma contagem\nexata, porque uma chave é lida de um código que todo app entrega.",[17,249,251],{"id":250},"por-que-os-avisos-apontam-para-a-chave-errada","Por que os avisos apontam para a chave errada",[10,253,254],{},"Só vemos o lado de fora desses apps, então não podemos dizer por quê. O que\nconseguimos mostrar é qual erro sobrevive.",[10,256,257,258,260,261,263,264,268],{},"Copiar a chave errada do Supabase é genuinamente fácil. Num projeto antigo ",[37,259,39],{},"\ne ",[37,262,160],{}," ficam lado a lado no mesmo painel do dashboard, têm o mesmo\ncomprimento e o mesmo formato, e\n",[28,265,267],{"href":266},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","nada quebra se você pegar a errada",".\nAinda assim aconteceu só três vezes em 30.998 apps, porque nada empurra você para\nlá. Colar qualquer uma das duas faz o app funcionar.",[10,270,271,272,276],{},"A tabela aberta tem uma força por trás. O Row Level Security é ligado, o app para\nde mostrar dados, uma policy que permite todo mundo é escrita para voltar a\nfuncionar, e a partir desse momento o dashboard informa a tabela como protegida.\nLigá-lo ",[28,273,275],{"href":274},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","não é o mesmo que estar protegido",".\nNosso scan classifica essa tabela como achado crítico num dia em que seu\ndashboard está mostrando a chave ligada e uma policy no lugar.",[17,278,280],{"id":279},"como-encontrar-de-graça-uma-chave-de-api-exposta-no-seu-app","Como encontrar de graça uma chave de API exposta no seu app",[10,282,283,284,287,288,291,292,294,295,298],{},"Comece na mão, porque custa cinco minutos e não exige instalar nada. Abra seu\nsite no ar, veja o código-fonte da página e procure por quatro sequências: ",[37,285,286],{},"AIza","\npara uma chave do Google, ",[37,289,290],{},"sk_"," para um segredo do Stripe ou de provedor de\nmodelo, ",[37,293,160],{}," para a chave do Supabase que ignora suas regras, e ",[37,296,297],{},"eyJ","\npara qualquer token do Supabase. Tudo o que voltar já está nas mãos de cada\nvisitante que você tem.",[10,300,301,302,304,305,307],{},"Isso cobre a página em si. O que escapa é o JavaScript que a página carrega\ndepois, e é justamente por isso que nosso próprio scanner abre um app num\nnavegador de verdade e lê os bundles em vez do HTML. Procurar na mão também não\ndiz se o token ",[37,303,297],{}," que você achou é a chave ",[37,306,39],{}," ou a secreta, porque as duas\ntêm o mesmo comprimento e o mesmo formato.",[10,309,310],{},"Nosso scan gratuito cobre as duas coisas. Ele carrega seu app num navegador de\nverdade, lê o código que chega de fato, decodifica cada token do Supabase e\ninforma o papel escrito dentro dele, de modo que uma chave publicável volta\nmarcada como correta em vez de enterrada num muro de vermelho. Você recebe uma\nnota, uma pontuação e as contagens na tela em cerca de 20 segundos, sem conta. Dê\num endereço de e-mail e você recebe também a lista detalhada, com uma correção\nescrita para o seu builder que dá para colar direto.",[10,312,313,314,316,317,321,322,207],{},"Três coisas que ele não faz, e são as razões de ser seguro rodar num app no ar:\nnunca faz login, nunca escreve nada e nunca guarda uma chave que encontra. Um\nsegredo exposto é guardado como uma dica mascarada do tipo ",[37,315,67],{},", e o\nvalor real é descartado. ",[28,318,320],{"href":319},"\u002F#scan","Escaneie seu app",", ou leia antes\n",[28,323,325],{"href":324},"\u002Fsecurity-scanner","o que cada uma das nove verificações olha",[17,327,329],{"id":328},"o-que-fazer-na-ordem-que-os-números-sugerem","O que fazer, na ordem que os números sugerem",[331,332,333],"key-takeaways",{},[334,335,336,344,347,350,353],"ul",{},[337,338,339,340,343],"li",{},"Identifique a chave antes de reagir a ela. O prefixo resolve para o Stripe e para as chaves novas do Supabase; numa chave antiga do Supabase, quem decide é o campo ",[37,341,342],{},"role"," dentro do token.",[337,345,346],{},"Se for uma chave do Google, restrinja em vez de esconder. Restrição de Sites, seu domínio, só as APIs que você usa, mais um teto de cota diária. De graça, uns cinco minutos, sem mudar código.",[337,348,349],{},"Se for uma chave secreta de verdade, rotacione primeiro. Apagá-la do código não fecha nada, porque o valor antigo continua no seu histórico de versões e nas cópias em cache do seu site.",[337,351,352],{},"Depois vá ler as regras das suas tabelas, que é onde os números colocam a exposição real. Comece pelas tabelas que guardam pessoas.",[337,354,355],{},"Confira cobrança e registros depois de qualquer exposição de chave secreta. Rotacionar interrompe o que vem a seguir, e não diz nada sobre o que já aconteceu.",[10,357,358,359,363,364,207],{},"Percorra a lista inteira de uma vez com a\n",[28,360,362],{"href":361},"\u002Fchecklist","checklist de segurança de 10 minutos",", que cobre a chave e as regras\nde tabela junto com as outras coisas que vale fechar num app recém-lançado. E se\na metade de banco de dados deste artigo é a que preocupa você, ela tem um\nlevantamento próprio:\n",[28,365,367],{"href":366},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","quem consegue ler seu banco de dados Supabase",{"title":369,"searchDepth":370,"depth":370,"links":371},"",3,[372,374,375,376,377,378,379],{"id":19,"depth":373,"text":20},2,{"id":47,"depth":373,"text":48},{"id":88,"depth":373,"text":89},{"id":210,"depth":373,"text":211},{"id":250,"depth":373,"text":251},{"id":279,"depth":373,"text":280},{"id":328,"depth":373,"text":329},"Noções de segurança","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcover-1200x630.png","Uma página de código de app com oito valores em forma de chave destacados, quase todos comuns e um desenhado em vermelho.","Uma chave de API exposta no seu frontend costuma ser uma chave do Google Maps. Escaneamos 30.998 apps vibe-coded e contamos quais segredos vazam de verdade.",false,"md",[387,390,393,396,399],{"q":388,"a":389},"Como sei se minha chave de API vazou?","Abra seu site no ar, veja o código-fonte da página e procure pelas formas: AIza para uma chave do Google, sk_ para um segredo do Stripe ou de provedor de modelo, e eyJ para um JWT do Supabase. Tudo que aparecer já está nas mãos de cada visitante. Nosso scan gratuito faz essa mesma leitura de fora e informa o que consegue ver em cerca de 20 segundos, sem conta para receber a nota.",{"q":391,"a":392},"Uma chave de API escrita direto no código é sempre um problema de segurança?","Não, e acreditar nisso é justamente o que ensina as pessoas a ignorar o aviso. Algumas chaves são publicadas de propósito: uma chave anon do Supabase, uma chave pk_ do Stripe e uma chave de configuração web do Firebase foram todas feitas para morar no navegador, e o que protege seus dados são as regras por trás delas. Uma chave secreta é o caso oposto e o lugar dela é um servidor. O prefixo diz qual das duas você tem na frente.",{"q":394,"a":395},"Disseram que minha chave do Supabase está exposta. É a ruim?","Quase certamente não. As duas chaves do Supabase se parecem, então leia o papel dentro do token ou confira o prefixo: anon e sb_publishable_ devem ser públicas, service_role e sb_secret_ não. Encontramos uma chave service_role em 3 apps de 30.998, então as chances pesam muito para a inofensiva. Se for mesmo a secreta, rotacione hoje no painel do Supabase.",{"q":397,"a":398},"Com o que eu deveria me preocupar no lugar?","Com as regras nas tabelas do seu banco. Dos apps em que conseguimos concluir essa verificação, mais da metade tinha ao menos uma tabela que respondia a uma requisição sem login nenhum, e em 394 deles a tabela aberta tinha nome de pessoas: users, profiles, customers, orders. Isso é muito mais comum do que qualquer chave vazada e muito mais silencioso, porque o app funciona exatamente igual nos dois casos.",{"q":400,"a":401},"Tirei a chave do meu código. Está fechado agora?","Não sozinho. O valor antigo continua existindo no seu histórico de versões e em qualquer cópia em cache da página, então quem já o recolheu pode seguir usando. O que realmente fecha a porta é rotacionar a chave no painel do provedor, e esse é o primeiro passo, não o último. Depois disso, confira a cobrança e os registros por uso que você não consiga explicar.","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",[404,405,406,407,408],"chave de api exposta no frontend","segredos no código do cliente","chave de api fixa no código","minha chave de api vazou","encontrar chaves de api expostas",{},true,"Chave de API exposta no frontend: 30.998 apps contados","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","2026-09-02",{"title":5,"description":383},"blog\u002Fwhat-secrets-leak-from-vibe-coded-apps",[417,418,419],"Uma chave de API exposta no seu frontend é quase sempre do tipo inofensivo. Encontramos uma chave digna de nota em 1.332 de 30.998 apps, e 1.080 delas só carregavam uma chave de API do Google.","A chave service_role do Supabase, contra a qual todo tutorial avisa, apareceu em 3 apps de 30.998. Uma chave secreta do Stripe também apareceu em 3.","Chaves que gastam dinheiro ou leem dados pela própria forma apareceram em 54 apps. Uma tabela aberta do Supabase apareceu em 2.096.","i8uAE6pR8WnyOxoBomUF2ajlzC4_4UE1899vkJwgQR4",[422,429,435,441,447,453,459,465,471,477,483,489,495,501,507,513,519,525,531,537,543,548,549,555,561,567,573,579,585,591,597,603,609,614,620,625,630,636,642,647,652,658],{"path":423,"title":424,"description":425,"published":426,"category":427,"image":428,"draft":384},"\u002Fblog\u002Fsupabase-backup-auth-users","Por que seu dump do Supabase não tem usuários dentro","Rode supabase db dump sozinho e você recebe a forma do seu banco e nenhuma das linhas dele, sem o schema auth onde seus usuários moram.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":430,"title":431,"description":432,"published":433,"category":380,"image":434,"draft":384},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domínio expirado, site fora do ar: o que acontece agora","Seu domínio expirou e seu site está fora do ar. O relógio que começa a correr, por que o certificado é o problema menor, e como conferir os dois.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":436,"title":437,"description":438,"published":439,"category":380,"image":440,"draft":384},"\u002Fblog\u002Fis-lovable-safe","O Lovable é seguro? O que vimos em 18.554 aplicativos Lovable","O Lovable é seguro? Passamos 18.554 aplicativos Lovable no ar por nove verificações. A plataforma foi a mais limpa de cinco. Os achados estavam nos aplicativos.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":442,"title":443,"description":444,"published":445,"category":380,"image":446,"draft":384},"\u002Fblog\u002Fvibe-coded-app-security-checklist","O checklist de segurança do vibe coding, em nove verificações","Um checklist de segurança do vibe coding com nove itens, cada um verificável no seu app de fora por qualquer pessoa, e cada um com um teste de uma linha.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":448,"title":449,"description":450,"published":451,"category":380,"image":452,"draft":384},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Uma chave secreta da Stripe no frontend pode mover dinheiro","Uma chave secreta da Stripe exposta no seu frontend pode reembolsar, cobrar e ler cada ficha de cliente que você tem. Sua chave pk_live_ é que deve estar aí.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":454,"title":455,"description":456,"published":457,"category":380,"image":458,"draft":384},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variáveis de ambiente do Vite expostas: o prefixo diz publique isto","Variáveis de ambiente do Vite expostas no seu app: fizeram o que o prefixo pediu. VITE_ e NEXT_PUBLIC_ significam publique isto, e a IA nunca soube o custo.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":460,"title":461,"description":462,"published":463,"category":380,"image":464,"draft":384},"\u002Fblog\u002Fbase44-source-maps","Segurança no Base44: o que um scan aponta e o que é seu para corrigir","Segurança no Base44 em 5.438 apps escaneados: três achados em quase todos são da plataforma, o source map é o selo do Base44, e a sua parte é uma lista curta.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":466,"title":467,"description":468,"published":469,"category":380,"image":470,"draft":384},"\u002Fblog\u002Fis-cursor-ai-safe","O Cursor AI é seguro? O editor, o código e o app que você publicou","O Cursor AI é seguro? Três perguntas em uma busca: o que o Cursor guarda, o que o código que ele escreve erra, e se o app que você publicou está aberto.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":472,"title":473,"description":474,"published":475,"category":380,"image":476,"draft":384},"\u002Fblog\u002Fis-replit-safe","O Replit é seguro? O que vimos em 3.042 aplicativos Replit no ar","O Replit é seguro? Passamos 3.042 aplicativos Replit no ar por nove verificações externas. Os achados estavam no aplicativo publicado, não no host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":478,"title":479,"description":480,"published":481,"category":427,"image":482,"draft":384},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: sua cópia do banco não tem nenhum arquivo","Um Supabase storage backup é uma tarefa à parte. Os backups do banco guardam a lista dos seus arquivos e nenhum deles, então cada upload fica quebrado.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":484,"title":485,"description":486,"published":487,"category":427,"image":488,"draft":384},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery do Supabase: preço e limites","O point-in-time recovery do Supabase rebobina seu banco para qualquer segundo da última semana. Custa $100 por mês além do Pro e cobre só o banco.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":490,"title":491,"description":492,"published":493,"category":427,"image":494,"draft":384},"\u002Fblog\u002Fsupabase-project-paused-recover","Projeto Supabase pausado? Seus dados continuam lá","O Supabase pausou seu projeto depois de uma semana sem atividade. Nada foi apagado, Restaurar fica ao lado do nome e você tem um ano antes disso mudar.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":496,"title":497,"description":498,"published":499,"category":380,"image":500,"draft":384},"\u002Fblog\u002Fsafest-ai-app-builder","Qual builder de apps com IA é mais seguro? 30.998 apps testados","Qual builder de apps com IA é mais seguro? Escaneamos 30.998 apps no ar do Lovable, Base44, Replit, v0 e Bolt. O builder não é o que decide sua nota.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":502,"title":503,"description":504,"published":505,"category":380,"image":506,"draft":384},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Ative Row Level Security em toda tabela do Supabase e comprove","Ativar Row Level Security no Supabase sem política fecha a tabela por completo. Uma política sem a chave ligada não faz nada. Aqui está o SQL, e o teste.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":508,"title":509,"description":510,"published":511,"category":380,"image":512,"draft":384},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": o que o aviso não vê","O Supabase marca \"RLS disabled in public\" como erro. Ele não diz nada sobre a política de leitura que deixa a sua tabela igualmente aberta.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":514,"title":515,"description":516,"published":517,"category":380,"image":518,"draft":384},"\u002Fblog\u002Frotate-supabase-service-role-key","Como rotacionar uma chave service_role do Supabase vazada","O Supabase manda fechar o vazamento primeiro. Outros guias mandam rotacionar agora. O que vale depende de para onde a sua chave service_role vazou.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":520,"title":521,"description":522,"published":523,"category":380,"image":524,"draft":384},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Scanners de segurança para vibe coding comparados, o nosso incluído","O melhor scanner de segurança para vibe coding depende de três perguntas que nenhuma lista de recursos responde. Dez ferramentas comparadas, com preços.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":526,"title":527,"description":528,"published":529,"category":380,"image":530,"draft":384},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: faça você mesmo as cinco verificações","Um Supabase security checker lê o seu app publicado em vez das configurações do projeto. Aqui estão as cinco verificações e como fazer cada uma sozinho.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":532,"title":533,"description":534,"published":535,"category":380,"image":536,"draft":384},"\u002Fblog\u002Fvibe-coding-security-scanner","Scanner de segurança para vibe coding: o que ele não vê","Um scanner de segurança para vibe coding lê seu app no ar, de fora. O que isso cobre, as quatro coisas que ele não consegue ver e como ler o resultado.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":538,"title":539,"description":540,"published":541,"category":380,"image":542,"draft":384},"\u002Fblog\u002Fmissing-security-headers","Cabeçalhos de segurança faltando: quando isso importa","Cabeçalhos de segurança faltando é o achado que nosso scanner mais imprime. Contra o que eles protegem e quando são a linha menos urgente do relatório.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":205,"title":544,"description":545,"published":546,"category":380,"image":547,"draft":384},"Sua chave de API da OpenAI está exposta no frontend. Troque-a.","Uma chave de API da OpenAI exposta no frontend não pode ser presa a um domínio. Troque-a hoje, mova a chamada para o seu servidor e limite o gasto.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":412,"title":5,"description":383,"published":413,"category":380,"image":402,"draft":384},{"path":550,"title":551,"description":552,"published":553,"category":427,"image":554,"draft":384},"\u002Fblog\u002Fsupabase-backup-tools-compared","Ferramentas de backup do Supabase comparadas, a nossa incluída","Quatro tipos de ferramenta de backup do Supabase, o que cada uma copia de verdade e quando uma GitHub Action gratuita ganha de pagar, nós inclusive.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":556,"title":557,"description":558,"published":559,"category":380,"image":560,"draft":384},"\u002Fblog\u002Freplit-secrets-explained","Como usar secrets no Replit, e o que ainda assim é publicado","Como usar secrets no Replit: adicionar um, ler de volta e resolver as duas causas do undefined. E as chaves que a ferramenta Secrets não consegue proteger.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":562,"title":563,"description":564,"published":565,"category":427,"image":566,"draft":384},"\u002Fblog\u002Fback-up-supabase-free-tier","Backups do plano gratuito do Supabase: como fazer sem terminal","No plano gratuito do Supabase não existe backup nenhum: a cópia é você que faz. Como fazer uma pelo painel e o que a rota do CSV deixa para trás.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":568,"title":569,"description":570,"published":571,"category":380,"image":572,"draft":384},"\u002Fblog\u002Fis-supabase-secure","O Supabase é seguro? É. Seu projeto é outra pergunta","O Supabase é seguro? A plataforma é auditada, criptografada e passa por pentests. A documentação deles diz onde isso termina e começam suas configurações.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":574,"title":575,"description":576,"published":577,"category":380,"image":578,"draft":384},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Onde ficam as chaves de API do Supabase: anon, service_role e URL","A URL do projeto, a chave anon e a chave service_role ficam todas numa página do painel. Aqui está onde ela fica, e qual dos quatro valores vai no seu app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":580,"title":581,"description":582,"published":583,"category":380,"image":584,"draft":384},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy no Supabase. E agora?","\"New row violates row-level security policy\" significa que o Supabase recusou uma escrita. O conserto rápido reabre a tabela para qualquer um.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":586,"title":587,"description":588,"published":589,"category":380,"image":590,"draft":384},"\u002Fblog\u002Fcors-wildcard-security-risk","Um curinga CORS é um risco de segurança? Quase nunca.","Um curinga CORS é um risco de segurança? Em geral é o padrão do seu builder e não entrega nada que o seu servidor já não desse a qualquer um que pedisse.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":592,"title":593,"description":594,"published":595,"category":427,"image":596,"draft":384},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching do Supabase não é backup. Ele só anda para a frente.","Por que o branching do Supabase não é backup: um branch começa sem os seus dados e um merge só leva o esquema. Para que ele serve e o que usar no lugar.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":598,"title":599,"description":600,"published":601,"category":427,"image":602,"draft":384},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Como restaurar um backup do Supabase, e o que quebra depois","Como restaurar um backup do Supabase pelo painel ou por um arquivo de dump, o que a restauração substitui e por que o seu app pode continuar quebrado no fim.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":604,"title":605,"description":606,"published":607,"category":380,"image":608,"draft":384},"\u002Fblog\u002Fsupabase-storage-bucket-public","Seu bucket do Supabase Storage é público. Isso é um problema?","Um bucket público do Supabase Storage significa que quem tem a URL de um arquivo pode abri-lo. Não significa que alguém possa listar o que está lá dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":30,"title":610,"description":611,"published":612,"category":380,"image":613,"draft":384},"Uma chave de API do Google no frontend é um problema?","Uma chave de API do Google exposta no seu frontend é a chave que nosso scanner mais encontra, e quase sempre está tudo bem. Um ajuste gratuito decide isso.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":615,"title":616,"description":617,"published":618,"category":427,"image":619,"draft":384},"\u002Fblog\u002Fai-agent-deleted-my-database","Um agente de IA apagou meus dados do Supabase. O que eu recupero?","Um agente de IA apagou dados do seu banco. O que você recupera já estava decidido antes de ele rodar, e os próximos minutos decidem o resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":366,"title":621,"description":622,"published":623,"category":380,"image":624,"draft":384},"Qualquer um consegue ler seu banco Supabase? Testamos 3.680 apps","Qualquer um consegue ler seu banco de dados Supabase sem fazer login? Escaneamos 30.998 apps no ar criadas com builders de IA e medimos quantas dizem que sim.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":626,"title":627,"description":628,"published":623,"category":380,"image":629,"draft":384},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps expostos: seu app está publicando o código original","Um source map exposto deixa qualquer um ler o código original do seu app, comentários incluídos. A verificação de 30 segundos e o que importa de verdade.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":631,"title":632,"description":633,"published":634,"category":380,"image":635,"draft":384},"\u002Fblog\u002Fsupabase-new-api-keys","As novas chaves de API do Supabase: qual vai no seu app?","O Supabase trocou anon e service_role por chaves publicáveis e secretas. Qual delas pertence ao seu app e qual nunca deve estar lá?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":637,"title":638,"description":639,"published":640,"category":427,"image":641,"draft":384},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","O Supabase faz backup do meu banco de dados? Depende do plano.","O Supabase faz backup do seu banco de dados? Todo dia nos planos pagos, e nada no gratuito. Como descobrir o que você tem e o que essa cópia não cobre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":274,"title":643,"description":644,"published":645,"category":380,"image":646,"draft":384},"O Supabase Row Level Security está ligado. A tabela continua pública.","Ligar o Supabase Row Level Security não protege uma tabela. Quem protege são as políticas, e a que consertou o seu app pode deixar qualquer um entrar.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":648,"title":649,"description":650,"published":645,"category":427,"image":651,"draft":384},"\u002Fblog\u002Fversion-history-is-not-a-backup","O histórico de versões não é backup. Ele não desfaz um delete.","Lovable e Bolt guardam um histórico de versões do seu código. Seu banco de dados é um serviço à parte, e voltar atrás não traz os seus dados de volta.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":653,"title":654,"description":655,"published":656,"category":427,"image":657,"draft":384},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Três formas de fazer backup de um banco Supabase, e o que falta","O painel, o pg_dump e um serviço gerenciado. O que cada um salva de verdade, o que deixa de fora sem avisar e qual sobrevive a perder a conta.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":266,"title":659,"description":660,"published":656,"category":380,"image":661,"draft":384},"Quais chaves de API são seguras no navegador e quais não são","Sua chave anon do Supabase foi feita para ser pública. Sua chave service_role não, e ela ignora todas as regras que você criar. Como diferenciar as duas.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1790150955889]