[{"data":1,"prerenderedAt":936},["ShallowReactive",2],{"blog-pt-aws-access-key-exposed-in-frontend":3,"blog-index-pt":407},{"id":4,"title":5,"body":6,"category":364,"cover":365,"coverAlt":366,"description":367,"draft":368,"extension":369,"faq":370,"image":384,"keywords":385,"meta":394,"navigation":395,"ogTitle":396,"path":397,"published":398,"seo":399,"stem":400,"tldr":401,"updated":398,"__hash__":406},"blog_pt\u002Fblog\u002Faws-access-key-exposed-in-frontend.md","Uma chave AWS exposta no seu frontend não é como uma chave OpenAI",{"type":7,"value":8,"toc":351},"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,261,281,291,308,311,315,338],[10,11,12,13,17],"p",{},"Alguém abre o seu aplicativo em um navegador, aperta F12 e encontra uma\nsequência começando com ",[14,15,16],"code",{},"AKIA"," no meio do seu código de frontend. Ou o GitHub\nescreve avisando que um commit que você subiu em março carrega uma credencial\nda AWS. O conselho que vem junto com qualquer um dos dois é sempre o mesmo:\nrotacione a chave. Para a maioria das chaves essa é quase a resposta inteira.",[10,19,20],{},"Aqui está a parte que guia após guia erra. Uma chave de acesso da AWS exposta\nno seu frontend não é uma chave que gasta dinheiro. É uma chave que abre\ncoisas, e as duas dão errado em direções diferentes. Uma chave que só gasta é\num cartão corporativo: alguém faz uma conta, você cancela o cartão, e o estrago\né um número que dá para ler num extrato. Uma chave que abre coisas é o molho de\nchaves do depósito. O que ela alcança depende do que escreveram nela quando foi\nfeita, e isso se lê numa única tela do seu console da AWS.",[22,23,25],"h2",{"id":24},"o-que-significa-akia-no-começo-de-uma-chave","O que significa AKIA no começo de uma chave?",[10,27,28,29,31,32,35,36,38],{},"Marca uma chave de acesso de longa duração, que pertence a um usuário da sua\nconta ou ao login root da conta. A AWS anota o prefixo na própria referência de\nidentificadores: ",[14,30,16],{}," para chaves de acesso e ",[14,33,34],{},"ASIA"," para as temporárias que\no serviço de tokens distribui. Então os quatro primeiros caracteres dizem com\nqual tipo você está lidando, e ",[14,37,16],{}," é o tipo sem prazo de validade. Funciona\naté alguém desligar.",[10,40,41,42,44],{},"Uma credencial da AWS são duas sequências, e uma requisição precisa das duas\npara sair assinada. A primeira é o identificador da chave de acesso, a parte\nque começa com ",[14,43,16],{},". A segunda é a chave de acesso secreta, uma sequência\nmais longa sem prefixo nenhum na frente. O identificador sozinho não assina\nnada.",[10,46,47,48,50,51,54,55,58],{},"Vale conferir isso antes de decidir o tamanho da manhã ruim, porque muda a\nresposta. Se o seu bundle carrega a sequência ",[14,49,16],{}," e nada parecido com a\nmetade secreta dela, um visitante que leu a sua página levou o nome da chave e\nnão a chave. Na prática as duas viajam juntas, porque o que botou uma no\nnavegador botou as duas: um par de variáveis de ambiente chamadas\n",[14,52,53],{},"AWS_ACCESS_KEY_ID"," e ",[14,56,57],{},"AWS_SECRET_ACCESS_KEY",", lidas por código que deveria\nrodar num servidor.",[60,61],"diagram",{"alt":62,"caption":63,"src":64},"Dois valores empilhados à esquerda: um curto em turquesa escrito AKIA e, abaixo, um mais longo cujo conteúdo está desenhado como blocos apagados. Os dois se juntam numa seta até um documento com um selo em forma de chave, marcado com um tique. Sob uma linha divisória, o valor AKIA sozinho leva a um xis.","As duas metades juntas assinam uma requisição. O identificador sozinho é um nome, e um nome não abre nada.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Ftwo-strings-one-signature-1600x640.png",[22,66,68],{"id":67},"o-que-alguém-consegue-fazer-com-a-minha-chave-de-acesso-da-aws","O que alguém consegue fazer com a minha chave de acesso da AWS?",[10,70,71],{},"O que as permissões dela permitirem, e nada além disso. Então são três\nrespostas.",[10,73,74,78],{},[75,76,77],"strong",{},"O que ela consegue ler?"," Todo bucket do S3 que a política listar, e todo\nobjeto dentro deles, inclusive aqueles para os quais você nunca colocou link\nnenhum. Um bucket que nada no seu aplicativo menciona não está escondido de uma\ncredencial que pode listá-lo.",[10,80,81,84],{},[75,82,83],{},"O que ela consegue gravar?"," Os mesmos lugares, e essa é a metade que se\nesquece. Uma chave que grava também sobrescreve e apaga, e um arquivo trocado\nno lugar fica exatamente igual ao que você enviou até alguém abrir.",[10,86,87,90],{},[75,88,89],{},"O que ela consegue ligar?"," Essa é a que tem taxímetro. Uma política larga o\nbastante para subir máquinas sobe máquinas, e isso cobra por hora enquanto\nestiver rodando. Nada na cópia que o navegador tem limita quanto da sua conta\nela alcança; a política é o único limite que existe.",[10,92,93,94,96],{},"A pior versão disso é uma chave feita para o login root da conta. A AWS diz nas\npróprias orientações sobre o usuário root que ele tem acesso irrestrito a todos\nos serviços da AWS, aos recursos e aos dados de cobrança, e desaconselha criar\nqualquer chave de acesso para ele. Se a chave na sua página começa com ",[14,95,16],{}," e\npertence ao usuário root, o que está exposto é a conta inteira e não um bucket.",[10,98,99],{},"Então não chute nada disso. Abra o IAM, ache o usuário dono da chave e leia as\npolíticas ligadas a ele. É uma tela, e ela responde às três perguntas acima.",[22,101,103],{"id":102},"basta-rotacionar","Basta rotacionar?",[10,105,106],{},"Desative hoje a chave exposta, e não ponha uma substituta no mesmo lugar.",[10,108,109],{},"Desativar é o primeiro passo certo e é mais suave do que soa. A AWS deixa um\nusuário ter até duas chaves de acesso ativas ao mesmo tempo, e isso existe\njustamente para que uma substituta suba antes de a antiga descer. Desativar\ndeixa a chave ali e desligada, e dá para religar; apagar é irreversível, e a\nmetade secreta de uma chave apagada não volta. Então desative, veja o que\nquebra e apague depois.",[10,111,112,113,115],{},"O que não encerra o assunto é criar uma chave nova e colar onde estava a\nantiga. O vazamento nunca foi de verdade sobre aquele valor. Foi sobre um\nnavegador segurando uma credencial sem prazo, e tudo o que a sua página baixa,\ncada visitante baixa. Uma sequência ",[14,114,16],{}," novinha no mesmo bundle volta como o\nmesmo achado no próximo escaneamento.",[10,117,118],{},"A AWS diz isso com todas as letras no guia de auditoria de segurança, falando\nde aplicativos móveis: eles nunca deveriam conter chaves de acesso embutidas,\nnem mesmo criptografadas. Um bundle de navegador se lê com mais facilidade do\nque um binário de aplicativo, então a mesma resposta vale aqui e dá menos\ntrabalho a um estranho.",[10,120,121,122,127],{},"Se você já achou a chave num lugar público, a ordem em que se trabalha importa,\ne ",[123,124,126],"a",{"href":125},"\u002Fblog\u002Fapi-key-leaked-what-to-do","o que fazer quando uma chave de API vaza","\ndeixa essa ordem pronta para chaves de todo tipo.",[22,129,131],{"id":130},"o-que-uma-presigned-url-faz-no-lugar","O que uma presigned URL faz no lugar",[10,133,134],{},"Deixa o navegador fazer uma coisa só com um arquivo só sem guardar credencial\nnenhuma.",[10,136,137],{},"O seu próprio servidor fica com a chave de acesso, onde um visitante não\nconsegue ler. Quando a sua página precisa colocar um arquivo no S3 ou tirar um\nde lá, ela pede ao seu servidor, e o seu servidor assina uma URL para aquele\nobjeto e aquela ação e devolve. O navegador usa a URL e não leva mais nada\njunto. A AWS descreve uma presigned URL como acesso temporário a objetos do S3\nsem credenciais da AWS, e o mesmo mecanismo cobre baixar e enviar.",[10,139,140],{},"De volta ao depósito. Uma presigned URL é receber o entregador na porta com a\ncaixa que ele veio buscar, em vez de passar o molho e torcer para ele achar. O\nque o entregador leva para de funcionar quando o relógio dele acaba.",[10,142,143,144,146,147,149],{},"Para o caso em que cada pessoa logada chega aos próprios arquivos, a AWS aponta\npara outro lugar de novo: as orientações sobre proteger chaves de acesso dizem\nque aplicativos móveis deveriam usar o Amazon Cognito para cuidar de\nidentidades em vez de embutir chaves de acesso. O que o Cognito dá ao navegador\né uma credencial temporária, do tipo ",[14,145,34],{}," do começo deste artigo, que para de\nfuncionar sozinha depois de um tempo. Uma cópia raspada da sua página numa\nterça já está morta na quarta, e essa é a única propriedade que uma chave\n",[14,148,16],{}," não tem.",[60,151],{"alt":152,"caption":153,"src":154},"Dois caminhos desenhados um acima do outro. Em cima, um navegador com uma chave ao lado, uma seta e uma estante de oito arquivos em duas prateleiras. Embaixo, o mesmo navegador, uma seta até um servidor que guarda a chave, e outra seta até um único arquivo com um mostrador de relógio ao lado.","O caminho de cima coloca no navegador algo que serve para todo arquivo, amanhã como hoje. O de baixo dá a ele um arquivo e um prazo.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fkey-or-url-1600x700.png",[22,156,158],{"id":157},"como-verifico-se-o-meu-aplicativo-entrega-uma-chave-da-aws","Como verifico se o meu aplicativo entrega uma chave da AWS?",[10,160,161],{},"Procure no que o navegador baixou, não no que está no seu projeto. São dois\narquivos diferentes, e o que conta é o que os seus visitantes recebem.",[10,163,164,167,168,170],{},[75,165,166],{},"No navegador."," Abra o seu site publicado, aperte F12 e procure ",[14,169,16],{}," no\nJavaScript carregado. Chrome e Edge procuram em todos os arquivos carregados de\numa vez pelo painel Sources.",[10,172,173,176,177,179,180,182,183,185,186,54,189,192,193,197],{},[75,174,175],{},"No seu projeto."," Procure ",[14,178,16],{},", ",[14,181,53],{}," e\n",[14,184,57],{},". Depois procure os dois prefixos que colocam um valor\nno bundle de propósito, ",[14,187,188],{},"VITE_",[14,190,191],{},"NEXT_PUBLIC_",", e leia cada valor atrás\ndeles.\n",[123,194,196],{"href":195},"\u002Fblog\u002Fvite-and-next-public-env-vars","Por que esses dois prefixos publicam tudo o que nomeiam","\né a mecânica por trás da maioria desses casos, e é uma regra do build que\nninguém digitou por engano.",[10,199,200,203,204,208],{},[75,201,202],{},"De fora."," O nosso scan gratuito lê o seu site publicado do jeito que um\nestranho leria e informa quais credenciais ele vê no que você publicou, essa\ninclusive. Leva uns 20 segundos e não pede conta:\n",[123,205,207],{"href":206},"\u002Fsecurity-scanner","escaneie seu aplicativo de graça",".",[10,210,211,212,216],{},"Em todos os aplicativos que escaneamos, esse é um achado raro: uma chave de\nacesso da AWS apareceu em 9 dos 31.056 aplicativos em que essa verificação foi\naté o fim. As que aparecem bem mais são as do Google, que em geral estão\ncertas, e as da OpenAI, que em geral não estão.\n",[123,213,215],{"href":214},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","O que realmente vaza de aplicativos feitos assim","\npõe todas lado a lado com os números.",[22,218,220],{"id":219},"o-que-a-chave-fez-enquanto-esteve-lá-fora","O que a chave fez enquanto esteve lá fora",[10,222,223],{},"Abra o histórico de eventos do CloudTrail e filtre pelo identificador da chave\nde acesso.",[10,225,226],{},"O histórico de eventos está ligado em toda conta da AWS sem precisar ativar\nnada, guarda os últimos 90 dias e não custa nada a mais. Cada entrada carrega o\nidentificador da chave que fez a chamada, então dá para reler o que a sua fez.\nIsso responde às perguntas de configuração: um bucket criado, uma política\nmudada, um usuário adicionado.",[10,228,229,230,233,234,237],{},"Aí vem a parte que é bom saber antes de ir olhar. O histórico guarda eventos de\n",[75,231,232],{},"management",". Ler um objeto do S3 é um evento de ",[75,235,236],{},"data",", e a AWS é\nexplícita ao dizer que os trails não registram esses por padrão e que eventos\nde data não aparecem no histórico. Ligá-los grava daquele momento em diante.",[10,239,240],{},"Então a leitura honesta é esta. Se a chave foi usada para mudar a sua conta, o\nregistro mostra. Se foi usada para baixar o conteúdo de um bucket,\nprovavelmente não mostra, e você decide o que contar aos seus clientes sabendo\nque pode ter acontecido.",[22,242,244],{"id":243},"como-manter-uma-chave-fora-do-próximo-build","Como manter uma chave fora do próximo build",[10,246,247,250],{},[75,248,249],{},"Uma credencial sai para o navegador na hora do build, então o próximo deploy\né o que precisa de atenção."," A chave que você tira hoje volta na tarde em que\nalguém acrescenta uma função que precisa do S3 e pede a um agente para ligar os\nfios.",[10,252,253],{},[75,254,255,256,260],{},"O ",[123,257,259],{"href":258},"\u002Fwebsite-monitoring","Reeve Monitor"," relê o seu site publicado por você:",[262,263,264,268,275,278],"ul",{},[265,266,267],"li",{},"as nove verificações a cada hora, em até três aplicativos",[265,269,270,271,274],{},"uma mensagem quando um resultado ",[75,272,273],{},"muda",", para que uma chave que chega numa terça não espere você olhar",[265,276,277],{},"se o aplicativo responde, a cada 60 segundos",[265,279,280],{},"um relatório mensal do que ele viu",[10,282,283],{},[75,284,285,286,290],{},"Se o seu aplicativo guarda os dados num projeto Supabase, o\n",[123,287,289],{"href":288},"\u002Fsupabase-backups","Reeve Care"," guarda uma cópia disso também:",[262,292,293,296,299,302,305],{},[265,294,295],{},"uma cópia criptografada do seu banco Supabase toda noite, guardada onde o seu projeto não alcança",[265,297,298],{},"cada cópia verificada antes de contar, contando as linhas de cada tabela",[265,300,301],{},"uma restauração em um clique quando você precisar",[265,303,304],{},"também os seus arquivos enviados, assim que você conectar uma credencial de Storage",[265,306,307],{},"tudo o que o Monitor faz",[10,309,310],{},"Cada uma dessas nove verificações descreve o que um estranho consegue alcançar.\nUma cópia do banco de ontem à noite responde à outra pergunta, a de o que\nalguém já alterou enquanto a chave esteve lá fora.",[22,312,314],{"id":313},"o-que-fazer-esta-semana","O que fazer esta semana",[316,317,318],"key-takeaways",{},[262,319,320,326,329,332,335],{},[265,321,322,323,325],{},"Abra o seu site publicado, aperte F12 e procure ",[14,324,16],{}," no JavaScript carregado. Esse é o arquivo que os seus visitantes têm, e é o único que conta.",[265,327,328],{},"Se achar uma, desative hoje no IAM. Desativar é reversível e vale na hora; apagar não é, e a metade secreta não volta.",[265,330,331],{},"Leia as políticas ligadas ao usuário dono da chave antes de decidir o tamanho disso. O que ela lê, o que ela grava e o que ela liga são três respostas separadas.",[265,333,334],{},"Troque o padrão em vez do valor. O seu servidor guarda a chave e assina uma presigned URL para um objeto, ou o Amazon Cognito dá ao navegador uma credencial temporária que expira sozinha.",[265,336,337],{},"Filtre o histórico de eventos do CloudTrail pela chave nos últimos 90 dias. Ele mostra o que a chave configurou, e não mostra quais arquivos ela leu a menos que os eventos de data já estivessem ligados.",[10,339,340,341,345,346,350],{},"Comece pela busca com F12, porque em um minuto ela resolve se você tem algum\nproblema. Se aparecer alguma coisa, a\n",[123,342,344],{"href":343},"\u002Fchecklist","checklist de segurança de 10 minutos"," cobre o resto do que um\naplicativo recém-lançado costuma deixar aberto, e\n",[123,347,349],{"href":348},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","mover um segredo para uma edge function","\né o padrão para toda chave que nunca deveria ter estado na página.",{"title":352,"searchDepth":353,"depth":353,"links":354},"",3,[355,357,358,359,360,361,362,363],{"id":24,"depth":356,"text":25},2,{"id":67,"depth":356,"text":68},{"id":102,"depth":356,"text":103},{"id":130,"depth":356,"text":131},{"id":157,"depth":356,"text":158},{"id":219,"depth":356,"text":220},{"id":243,"depth":356,"text":244},{"id":313,"depth":356,"text":314},"Noções de segurança","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcover-1200x630.png","Uma página de código do aplicativo com um valor curto aceso e um longo encoberto, uma chave atravessada no canto dela e, atrás, uma estante de arquivos.","Uma chave de acesso da AWS exposta no seu frontend lê e grava no seu armazenamento. A solução costuma ser uma presigned URL, não uma chave nova.",false,"md",[371,374,376,379,381],{"q":372,"a":373},"Alguma vez é seguro colocar chaves da AWS no código do frontend?","Não. A AWS diz isso no próprio guia de auditoria de segurança, falando de aplicativos móveis: um aplicativo nunca deveria conter chaves de acesso embutidas, nem mesmo criptografadas. Um bundle de navegador se lê com mais facilidade do que um binário de aplicativo, então a mesma resposta vale aqui e dá menos trabalho a um estranho. Se a sua página precisa mesmo chegar ao S3, os caminhos previstos são uma presigned URL assinada pelo seu próprio servidor, ou credenciais temporárias do Amazon Cognito, que expiram sozinhas.",{"q":68,"a":375},"Exatamente o que as permissões por trás dela permitirem, e é por isso que não existe uma resposta só. Uma chave presa a um usuário com acesso de leitura a um bucket lê esse bucket. Uma chave presa a um administrador faz tudo o que um administrador faz, inclusive ligar máquinas que cobram por hora. Uma chave do usuário root da conta é o pior caso, porque a AWS afirma que o usuário root tem acesso irrestrito a todos os serviços, recursos e dados de cobrança. Abra o IAM e leia as políticas ligadas à chave antes de decidir o quanto se preocupar.",{"q":377,"a":378},"O que é uma presigned URL?","Uma URL longa que deixa um navegador fazer uma coisa só com um arquivo só no S3, por um número fixo de segundos, sem guardar nenhuma credencial da AWS. O seu próprio servidor guarda a chave e assina a URL quando pedem. A AWS descreve presigned URLs como acesso temporário a objetos do S3 sem credenciais da AWS, e elas servem tanto para baixar quanto para enviar.",{"q":158,"a":380},"Procure no que o seu navegador baixou, não no que está no seu projeto. Abra o seu site publicado, aperte F12 e procure AKIA no JavaScript carregado. Depois procure no seu projeto por AKIA, AWS_ACCESS_KEY_ID e AWS_SECRET_ACCESS_KEY, e por qualquer nome de variável que comece com VITE_ ou NEXT_PUBLIC_ e guarde uma delas, porque são esses prefixos que colocam um valor no bundle logo de início.",{"q":382,"a":383},"Minha chave da AWS está no GitHub. E agora?","Desative primeiro no IAM, o que é reversível e vale na hora, e depois crie uma substituta para o servidor que precisava dela. Tirar a chave do código não fecha nada, porque o valor antigo continua no seu histórico de commits e em todo clone que alguém tenha feito. Em seguida abra o histórico de eventos do CloudTrail e filtre pela chave para ver o que ela fez.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",[386,387,388,389,390,391,392,393],"chave de acesso aws exposta no frontend","chave aws no frontend","chave de acesso aws vazada","chave akia exposta","aws secret access key no javascript","credenciais aws no lado do cliente","é seguro usar chaves aws no react","chave aws no github",{},true,"Chave de acesso da AWS exposta no seu frontend?","\u002Fblog\u002Faws-access-key-exposed-in-frontend","2026-10-12",{"title":5,"description":367},"blog\u002Faws-access-key-exposed-in-frontend",[402,403,404,405],"Uma chave de acesso da AWS exposta no seu frontend é um problema diferente do de uma chave que só consegue gastar dinheiro. O que ela alcança quem decide são as permissões dela.","Duas sequências assinam uma requisição da AWS: um identificador que começa com `AKIA` e uma metade secreta. Uma sem a outra não assina nada.","Uma chave nova colada no mesmo lugar é o mesmo achado com outro valor. A solução é uma presigned URL, para que o navegador não guarde credencial nenhuma.","Encontramos uma em 9 dos 31.056 aplicativos escaneados em que essa verificação foi até o fim.","1s9u_x12RN0KFNRwBj1jcfMcuD4nRrr62_BhEMFAurs",[408,414,420,426,432,438,444,450,456,462,468,475,481,487,493,499,505,511,517,523,529,535,541,547,553,559,565,571,577,578,584,590,595,601,607,613,618,624,630,636,642,648,654,660,666,672,677,683,689,695,701,707,713,719,724,730,736,742,748,754,760,766,772,778,784,790,796,802,808,814,819,825,831,837,843,849,855,861,867,873,879,885,891,897,902,908,914,920,925,931],{"path":409,"title":410,"description":411,"published":412,"category":364,"image":413,"draft":368},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\", explicado","Supabase \"max client connections reached\": o pooler não tem lugar para mais um cliente. A porta da sua string de conexão define o limite.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":415,"title":416,"description":417,"published":418,"category":364,"image":419,"draft":368},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Erro do Supabase: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\": o Google está desativado no seu projeto Supabase. Como ativar e corrigir o redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":421,"title":422,"description":423,"published":424,"category":364,"image":425,"draft":368},"\u002Fblog\u002Fviolates-foreign-key-constraint","Erro do Supabase \"violates foreign key constraint\" ao inserir","Supabase \"insert or update on table violates foreign key constraint\": sua linha aponta para uma linha que não existe. Qual, por quê, e como corrigir.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":427,"title":428,"description":429,"published":430,"category":364,"image":431,"draft":368},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Erro do Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": uma coluna obrigatória chegou vazia. De onde veio o null, e como corrigir.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":433,"title":434,"description":435,"published":436,"category":364,"image":437,"draft":368},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": para onde foi a sessão","\"Auth session missing!\" é o supabase-js sem achar nenhuma sessão logada e sem chegar a perguntar ao Supabase. Para onde foi a sessão, e a correção.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":439,"title":440,"description":441,"published":442,"category":364,"image":443,"draft":368},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": ninguém está logado","\"invalid claim: missing sub claim\": o Supabase Auth recebeu um token autêntico sem nenhum usuário, a chave do projeto no lugar de uma sessão.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":445,"title":446,"description":447,"published":448,"category":364,"image":449,"draft":368},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": a causa real","\"Failed to send a request to the Edge Function\": o navegador não recebeu uma resposta legível. O console dele diz por quê e se a sua função rodou.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":451,"title":452,"description":453,"published":454,"category":364,"image":455,"draft":368},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Por que o Supabase redireciona links de e-mail para localhost:3000","Se o Supabase redireciona para localhost:3000, a Site URL nunca foi trocada ou o seu endereço falta em Redirect URLs. A solução, e o curinga a evitar.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":457,"title":458,"description":459,"published":460,"category":364,"image":461,"draft":368},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" num link novo","Num link enviado há um minuto, \"Email link is invalid or has expired\" no Supabase costuma significar que um filtro de e-mail o usou antes. Como resolver.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":463,"title":464,"description":465,"published":466,"category":364,"image":467,"draft":368},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\", explicado","Supabase \"canceling statement due to statement timeout\": uma consulta passou do limite do seu papel, 3 segundos para um visitante. Veja antes a política RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":469,"title":470,"description":471,"published":472,"category":473,"image":474,"draft":368},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" no Supabase, e o que vai junto","\"Database error deleting user\" no Supabase: seu banco recusou a exclusão. O motivo está nos seus logs, e a correção decide o que mais é apagado.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":476,"title":477,"description":478,"published":479,"category":364,"image":480,"draft":368},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" no Supabase","O webhook do Stripe numa Edge Function do Supabase diz \"No signatures found matching the expected signature\"? São duas causas. Continue verificando.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":482,"title":483,"description":484,"published":485,"category":364,"image":486,"draft":368},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" no Supabase: as três causas","O Supabase diz \"Invalid login credentials\" para senha errada, e-mail desconhecido e conta Google. Como saber qual é, e por que é vago.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":488,"title":489,"description":490,"published":491,"category":364,"image":492,"draft":368},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": o erro real","\"Edge Function returned a non-2xx status code\" quer dizer que sua função do Supabase respondeu com um erro. Veja onde ler o erro real.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":494,"title":495,"description":496,"published":497,"category":364,"image":498,"draft":368},"\u002Fblog\u002Fcertificate-not-trusted","Certificado não confiável: três causas além do vencimento","Certificado não confiável mesmo com a data certa? Ele cita outro endereço, assinou a si mesmo ou falta um elo na cadeia. Veja como saber qual.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":500,"title":501,"description":502,"published":503,"category":364,"image":504,"draft":368},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": leia as aspas","Supabase \"invalid input syntax for type uuid\": seu app enviou algo que não é um id. Leia as aspas, segure a consulta, mantenha a coluna.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":506,"title":507,"description":508,"published":509,"category":364,"image":510,"draft":368},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\", explicado","Supabase \"duplicate key value violates unique constraint\": o valor já está em uso. Ache a coluna, escolha uma correção e tire o valor da tela.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":512,"title":513,"description":514,"published":515,"category":364,"image":516,"draft":368},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\" e a tabela está lá","Supabase \"relation does not exist\" ou PGRST205: nenhuma tabela tem esse nome nesse schema. Quatro verificações, e o que expor um schema abre.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":518,"title":519,"description":520,"published":521,"category":364,"image":522,"draft":368},"\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\" mostra os nomes de argumentos que seu app enviou. Compare-os com a função.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":524,"title":525,"description":526,"published":527,"category":364,"image":528,"draft":368},"\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\" costuma ser um nome que não bate. Quatro verificações e a linha que recarrega.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":530,"title":531,"description":532,"published":533,"category":364,"image":534,"draft":368},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": dois limites, um só código","Supabase \"Email Rate Limit Exceeded\" limita cada email que seu projeto envia: 2 por hora no remetente embutido. O que conta e como aumentar.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":536,"title":537,"description":538,"published":539,"category":364,"image":540,"draft":368},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 causas","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" desconecta seus usuários. Três causas, e como o log do Auth separa cada uma.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":542,"title":543,"description":544,"published":545,"category":364,"image":546,"draft":368},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": três causas","Supabase \"permission denied for schema public\" é um grant que falta no schema. O que o removeu, e a linha que o devolve.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":548,"title":549,"description":550,"published":551,"category":364,"image":552,"draft":368},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": as três coisas que isso significa","Supabase \"Bucket not found\" é uma de três coisas: um link público para um bucket privado, um nome que não bate exatamente ou o projeto errado.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":554,"title":555,"description":556,"published":557,"category":364,"image":558,"draft":368},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: qual chave parou de funcionar?","Um erro Supabase invalid JWT é o PGRST301: um token assinado não passou na verificação. Num projeto novo isso é a sessão, não a chave de API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":560,"title":561,"description":562,"published":563,"category":364,"image":564,"draft":368},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" quase sempre é nenhuma","O Supabase devolve PGRST116, \"JSON object requested, multiple (or no) rows returned\", quando a consulta não achou nada. Linha escondida parece ausente.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":566,"title":567,"description":568,"published":569,"category":364,"image":570,"draft":368},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" no Supabase: onde olhar","\"Database error saving new user\" quer dizer que algo preso ao seu cadastro no Supabase falhou e tudo foi desfeito. O erro real está nos seus logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":572,"title":573,"description":574,"published":575,"category":364,"image":576,"draft":368},"\u002Fblog\u002Fwhat-is-supabase","O que é Supabase? O banco de dados que seu builder escolheu","O que é Supabase: o banco de dados, o login e o armazenamento de arquivos do seu app. O Supabase cuida dos servidores; as regras das suas linhas são suas.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":397,"title":5,"description":367,"published":398,"category":364,"image":384,"draft":368},{"path":579,"title":580,"description":581,"published":582,"category":364,"image":583,"draft":368},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" ao enviar","\"New row violates row-level security policy for table objects\" quer dizer que o seu envio não tem regra insert. Deixar o bucket público não cria nenhuma.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":585,"title":586,"description":587,"published":588,"category":364,"image":589,"draft":368},"\u002Fblog\u002Fbase44-security-scan","Scan de segurança do Base44: o que só ele enxerga","O scan de segurança do Base44 verifica sete tipos de problema por dentro. Esta é a metade que ele lê e mais ninguém, e a metade que ele nunca olha.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":125,"title":591,"description":592,"published":593,"category":364,"image":594,"draft":368},"Sua chave de API vazou. A ordem em que agir","Uma chave de API vazou e você não sabe o que fazer primeiro. Nem toda chave no seu frontend é um vazamento, e a ordem importa mais que a pressa.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":596,"title":597,"description":598,"published":599,"category":364,"image":600,"draft":368},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sem desligar o RLS","\"Infinite recursion detected in policy for relation\" significa que a sua policy perguntou à tabela que ela protege. Veja como quebrar o círculo.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":602,"title":603,"description":604,"published":605,"category":364,"image":606,"draft":368},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" no Supabase, e a correção errada","\"No API key found in request\" significa que sua requisição chegou ao Supabase sem chave. Quase toda resposta aponta para as regras do seu banco.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":608,"title":609,"description":610,"published":611,"category":364,"image":612,"draft":368},"\u002Fblog\u002Fis-base44-safe","O Base44 é seguro? O que vimos em 5.442 apps Base44","O Base44 é seguro? Rodamos nove verificações em 5.442 apps Base44 no ar. Quase todas tiraram B por motivos que o dono nunca escolheu.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":348,"title":614,"description":615,"published":616,"category":364,"image":617,"draft":368},"Esconder uma chave de API: mova para uma Edge Function do Supabase","Esconder uma chave de API é tirá-la do navegador, e uma Edge Function do Supabase é o menor lugar para guardá-la. Dois passos em volta pesam mais.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":619,"title":620,"description":621,"published":622,"category":364,"image":623,"draft":368},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Seu arquivo .env está exposto? Os doze caminhos para testar","Seu arquivo .env está exposto no seu próprio servidor web? Doze endereços dizem isso em um minuto, e um acerto significa que tudo nele já é público.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":625,"title":626,"description":627,"published":628,"category":364,"image":629,"draft":368},"\u002Fblog\u002Fis-v0-safe","Segurança do v0: os 1.790 aplicativos v0 escaneados tiraram A","A segurança do v0 medida em 1.790 aplicativos v0 no ar: todos tiraram A. Só 17 citavam um banco de dados, e é sobretudo isso que esse A mede.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":631,"title":632,"description":633,"published":634,"category":364,"image":635,"draft":368},"\u002Fblog\u002Fis-bolt-safe","O Bolt é seguro? O que vimos em 1.123 aplicativos Bolt","O Bolt é seguro? Passamos 1.123 aplicativos Bolt no ar por nove verificações. A hospedagem saiu limpa. Os achados: chaves e tabelas abertas nos aplicativos.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":637,"title":638,"description":639,"published":640,"category":364,"image":641,"draft":368},"\u002Fblog\u002Fis-supabase-down-or-your-app","O Supabase caiu ou o problema é o seu app? Como saber","O Supabase caiu ou o problema é o seu app? Um projeto pausado, um banco cheio e um erro seu parecem iguais. Quatro verificações separam os casos.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":643,"title":644,"description":645,"published":646,"category":364,"image":647,"draft":368},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","O Supabase criptografa meus dados? Sim. Veja o que isso impede","O Supabase criptografa os dados? Sim: AES-256 em repouso, TLS em trânsito, SOC 2 e ISO 27001. O que cada um cobre, e o vazamento que nenhum deles impede.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":649,"title":650,"description":651,"published":652,"category":364,"image":653,"draft":368},"\u002Fblog\u002Fsupabase-free-plan-limits","O Supabase é gratuito? Sim, com estes limites e sem backups","Sim: o plano gratuito do Supabase vai até 500 MB de banco e 5 GB de egress, sem nenhum backup. O que para em cada limite e o que muda no Pro de $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":655,"title":656,"description":657,"published":658,"category":473,"image":659,"draft":368},"\u002Fblog\u002Ftest-your-supabase-backup","Teste o backup do seu Supabase antes do dia em que precisar","Como testar o backup do seu Supabase: restaurar num projeto de teste, contar as linhas, entrar e procurar a linha que falta num arquivo cortado.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":661,"title":662,"description":663,"published":664,"category":473,"image":665,"draft":368},"\u002Fblog\u002Fsupabase-backup-github-action","Backup grátis do Supabase com uma GitHub Action, e a pegadinha","Um backup do Supabase com GitHub Action é grátis e serve para muitos apps. O workflow, a connection string certa e o egress de cada execução.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":667,"title":668,"description":669,"published":670,"category":473,"image":671,"draft":368},"\u002Fblog\u002Fdownload-your-supabase-backup","Por que você não consegue baixar seu backup do Supabase","Você não consegue baixar seu backup do Supabase num projeto atual, porque a cópia diária é um snapshot físico. Como conferir e como ter uma cópia só sua.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":673,"title":674,"description":675,"published":670,"category":364,"image":676,"draft":368},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": o grant que falta","A partir de 30 de outubro, uma tabela nova no Supabase responde \"permission denied for table\" até receber um grant. O e-mail mostra só metade.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":678,"title":679,"description":680,"published":681,"category":364,"image":682,"draft":368},"\u002Fblog\u002Fopen-api-endpoint-exposed","Um endpoint de API aberto é um problema? Leia o JSON","Seu scan apontou um endpoint de API aberto. Se isso importa depende do que voltou, e a maioria dos que encontramos era da própria plataforma.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":684,"title":685,"description":686,"published":687,"category":364,"image":688,"draft":368},"\u002Fblog\u002Flovable-security-scan","Escaneamento de segurança do Lovable: o que ele não prova","Escaneamento de segurança do Lovable: o que o Quick scan e o Deep scan checam, quando cada um roda, e a única coisa que nenhum escaneamento por dentro prova.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":690,"title":691,"description":692,"published":693,"category":473,"image":694,"draft":368},"\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","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":696,"title":697,"description":698,"published":699,"category":364,"image":700,"draft":368},"\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":702,"title":703,"description":704,"published":705,"category":364,"image":706,"draft":368},"\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":708,"title":709,"description":710,"published":711,"category":364,"image":712,"draft":368},"\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":714,"title":715,"description":716,"published":717,"category":364,"image":718,"draft":368},"\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":195,"title":720,"description":721,"published":722,"category":364,"image":723,"draft":368},"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":725,"title":726,"description":727,"published":728,"category":364,"image":729,"draft":368},"\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":731,"title":732,"description":733,"published":734,"category":364,"image":735,"draft":368},"\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":737,"title":738,"description":739,"published":740,"category":364,"image":741,"draft":368},"\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":743,"title":744,"description":745,"published":746,"category":473,"image":747,"draft":368},"\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":749,"title":750,"description":751,"published":752,"category":473,"image":753,"draft":368},"\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":755,"title":756,"description":757,"published":758,"category":473,"image":759,"draft":368},"\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":761,"title":762,"description":763,"published":764,"category":364,"image":765,"draft":368},"\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":767,"title":768,"description":769,"published":770,"category":364,"image":771,"draft":368},"\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":773,"title":774,"description":775,"published":776,"category":364,"image":777,"draft":368},"\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":779,"title":780,"description":781,"published":782,"category":364,"image":783,"draft":368},"\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":785,"title":786,"description":787,"published":788,"category":364,"image":789,"draft":368},"\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. Oito ferramentas comparadas, com preços.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":364,"image":795,"draft":368},"\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":797,"title":798,"description":799,"published":800,"category":364,"image":801,"draft":368},"\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":803,"title":804,"description":805,"published":806,"category":364,"image":807,"draft":368},"\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":809,"title":810,"description":811,"published":812,"category":364,"image":813,"draft":368},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","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":214,"title":815,"description":816,"published":817,"category":364,"image":818,"draft":368},"Chave de API exposta no frontend: o que 30.998 apps entregam","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.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":820,"title":821,"description":822,"published":823,"category":473,"image":824,"draft":368},"\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":826,"title":827,"description":828,"published":829,"category":364,"image":830,"draft":368},"\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":832,"title":833,"description":834,"published":835,"category":473,"image":836,"draft":368},"\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":838,"title":839,"description":840,"published":841,"category":364,"image":842,"draft":368},"\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":844,"title":845,"description":846,"published":847,"category":364,"image":848,"draft":368},"\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":850,"title":851,"description":852,"published":853,"category":364,"image":854,"draft":368},"\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":856,"title":857,"description":858,"published":859,"category":364,"image":860,"draft":368},"\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":862,"title":863,"description":864,"published":865,"category":473,"image":866,"draft":368},"\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":868,"title":869,"description":870,"published":871,"category":473,"image":872,"draft":368},"\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":874,"title":875,"description":876,"published":877,"category":364,"image":878,"draft":368},"\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":880,"title":881,"description":882,"published":883,"category":364,"image":884,"draft":368},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","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":886,"title":887,"description":888,"published":889,"category":473,"image":890,"draft":368},"\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":892,"title":893,"description":894,"published":895,"category":364,"image":896,"draft":368},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","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":898,"title":899,"description":900,"published":895,"category":364,"image":901,"draft":368},"\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":903,"title":904,"description":905,"published":906,"category":364,"image":907,"draft":368},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: é a mesma coisa que a anon key?","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":909,"title":910,"description":911,"published":912,"category":473,"image":913,"draft":368},"\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":915,"title":916,"description":917,"published":918,"category":364,"image":919,"draft":368},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","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":921,"title":922,"description":923,"published":918,"category":473,"image":924,"draft":368},"\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":926,"title":927,"description":928,"published":929,"category":473,"image":930,"draft":368},"\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":932,"title":933,"description":934,"published":929,"category":364,"image":935,"draft":368},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","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",1794213649349]