[{"data":1,"prerenderedAt":998},["ShallowReactive",2],{"blog-pt-api-key-leaked-what-to-do":3,"blog-index-pt":645},{"id":4,"title":5,"body":6,"category":601,"cover":602,"coverAlt":603,"description":604,"draft":605,"extension":606,"faq":607,"image":622,"keywords":623,"meta":632,"navigation":633,"ogTitle":634,"path":635,"published":636,"seo":637,"stem":638,"tldr":639,"updated":636,"__hash__":644},"blog_pt\u002Fblog\u002Fapi-key-leaked-what-to-do.md","Sua chave de API vazou. A ordem em que agir",{"type":7,"value":8,"toc":587},"minimark",[9,13,16,21,24,32,35,57,65,69,72,79,82,88,94,100,104,267,270,280,302,306,309,363,368,372,375,382,385,388,392,395,404,409,414,424,428,431,434,437,440,445,449,455,463,474,483,501,510,527,538,542,579],[10,11,12],"p",{},"O aviso costuma chegar por um relatório de varredura, pelo GitHub avisando que\napareceu um segredo em um dos seus repositórios, ou por alguém que apertou F12\nno seu site e mandou um print. Por onde quer que tenha chegado, você já sabe que\numa chave de API sua vazou e não sabe o que fazer primeiro.",[10,14,15],{},"Esta é a parte que guia após guia erra: eles dão a mesma resposta para qualquer\nchave, e a resposta é sempre rotacionar. Algumas dessas chaves deveriam mesmo\nser públicas e não precisam de nada. Entre as outras, algumas estão engordando\numa fatura enquanto você lê isto, e outras fizeram todo o estrago no dia do\ndeploy. São três situações diferentes, e o primeiro passo é outro em cada uma.",[17,18,20],"h2",{"id":19},"primeiro-essa-chave-é-mesmo-um-segredo","Primeiro: essa chave é mesmo um segredo?",[10,22,23],{},"Muitas vezes não, e os números são desequilibrados o bastante para dizer isso\ncom todas as letras.",[10,25,26,27,31],{},"Varremos 31.056 aplicativos no ar e lemos o JavaScript que cada um entrega ao\nnavegador. A verificação que procura credenciais conseguiu responder em todos, e\n1.332 voltaram com pelo menos uma chave que merecia aviso. ",[28,29,30],"strong",{},"1.142 delas eram\nchaves de API do Google",", que é o único tipo do grupo que normalmente está\nexatamente onde deveria estar.",[10,33,34],{},"Uma chave de API do Google numa página web é o que faz o Google Maps funcionar.\nA chave diz qual projeto paga, e o que impede um estranho de gastar por sua\nconta é a restrição colocada na chave, e não o sigilo dela. A orientação do\npróprio Google é direta nas duas metades: \"Unrestricted API keys are insecure\",\ne \"You are financially responsible for charges caused by abuse of unrestricted\nAPI keys.\" O conserto para uma chave dessas é abri-la no Cloud Console e\nacrescentar duas restrições, uma nomeando o seu site e outra nomeando as APIs\nque você realmente chama. A chave em si nunca muda.",[10,36,37,38,42,43,46,47,50,51,56],{},"A outra família que mora no navegador são as chaves publicáveis. Uma chave da\nStripe ",[39,40,41],"code",{},"pk_live_",", e uma do Supabase ",[39,44,45],{},"sb_publishable_"," ou ",[39,48,49],{},"anon",", foram feitas\npara ser lidas por cada visitante que você tem.\n",[52,53,55],"a",{"href":54},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Quais chaves são seguras no seu frontend","\né a versão de quatro caracteres desse teste.",[10,58,59,60,64],{},"Se você preferir não percorrer o bundle na mão, a nossa varredura gratuita lê o\nseu site no ar, lista as chaves que enxerga de fora e diz de que tipo é cada\numa: ",[52,61,63],{"href":62},"\u002Fsecurity-scanner","escaneie seu aplicativo",". Leva uns 20 segundos e não\npede conta.",[17,66,68],{"id":67},"minha-chave-de-api-vazou-o-que-faço-primeiro","Minha chave de API vazou. O que faço primeiro?",[10,70,71],{},"Descubra se a chave tem um medidor.",[10,73,74,75,78],{},"Uma chave com medidor cobra de você a cada requisição. A do Google, a da OpenAI,\na da Anthropic e uma chave da AWS com as permissões erradas atrás dela são todas\nmedidores: o tráfego de outra pessoa cai na sua fatura, num ritmo que essa\npessoa escolhe e que você não vê. Uma chave sem medidor lê ou escreve os seus\ndados. Uma chave ",[39,76,77],{},"service_role"," do Supabase é o exemplo mais claro, e nada nela\ncusta dinheiro por hora.",[10,80,81],{},"Essa única pergunta define a ordem.",[10,83,84,87],{},[28,85,86],{},"Se a chave tem medidor, pare agora."," A funcionalidade que a usava fica\nquebrada até você publicar a substituta, e essa é a troca certa, porque a fatura\né a única parte disto que continua crescendo enquanto você planeja.",[10,89,90,93],{},[28,91,92],{},"Se a chave lê dados e foi publicada no seu bundle, a leitura já aconteceu.","\nTodo visitante que carregou a página tem uma cópia, e todo robô que foi atrás\nexatamente dessa sequência de caracteres também. Nada piora enquanto você\ndescobre a ordem certa, e o que vale acertar é não se trancar para fora do seu\npróprio aplicativo no caminho.",[95,96],"diagram",{"alt":97,"caption":98,"src":99},"Duas faixas, cada uma começando com a mesma chave. Na de cima a chave leva a um mostrador cujo ponteiro já girou bastante, e segue para uma pilha de moedas, tudo em âmbar. Na de baixo a chave leva a uma tabela com todas as linhas acesas em vermelho, e no lugar do mostrador há um círculo vazio pontilhado.","A chave de cima está custando dinheiro enquanto você lê isto. A de baixo fez tudo o que ia fazer no dia do deploy.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fdoes-it-have-a-meter-1600x660.png",[17,101,103],{"id":102},"o-que-cada-tipo-de-chave-realmente-consegue-fazer","O que cada tipo de chave realmente consegue fazer",[105,106,107,129],"table",{},[108,109,110],"thead",{},[111,112,113,117,120,123,126],"tr",{},[114,115,116],"th",{},"Chave",[114,118,119],{},"Gasta dinheiro",[114,121,122],{},"Lê seus dados",[114,124,125],{},"Dá para restringir no lugar?",[114,127,128],{},"Substituir quebra o aplicativo?",[130,131,132,154,169,188,205,227,248],"tbody",{},[111,133,134,142,145,148,151],{},[135,136,137,138,46,140],"td",{},"Supabase ",[39,139,45],{},[39,141,49],{},[135,143,144],{},"Não",[135,146,147],{},"Só as linhas que suas regras permitem",[135,149,150],{},"O lugar dela é o navegador",[135,152,153],{},"Não se aplica",[111,155,156,161,163,165,167],{},[135,157,158,159],{},"Stripe ",[39,160,41],{},[135,162,144],{},[135,164,144],{},[135,166,150],{},[135,168,153],{},[111,170,171,177,180,182,185],{},[135,172,173,174],{},"Google ",[39,175,176],{},"AIza…",[135,178,179],{},"Sim, na sua fatura do Cloud",[135,181,144],{},[135,183,184],{},"Sim, e o Google diz para tentar isso primeiro",[135,186,187],{},"Restringir não. Rotacionar pode.",[111,189,190,193,196,199,202],{},[135,191,192],{},"Chave da OpenAI ou da Anthropic",[135,194,195],{},"Sim, no ritmo de um estranho",[135,197,198],{},"Os arquivos e assistentes do projeto",[135,200,201],{},"Não existe variante publicável",[135,203,204],{},"Sim, até um servidor seu guardá-la",[111,206,207,215,218,221,224],{},[135,208,158,209,46,212],{},[39,210,211],{},"sk_live_",[39,213,214],{},"rk_live_",[135,216,217],{},"Sim",[135,219,220],{},"Sim, clientes e registros de pagamento",[135,222,223],{},"Uma chave restrita é a versão estreita",[135,225,226],{},"Não, há uma janela de sete dias",[111,228,229,236,239,242,245],{},[135,230,231,232,235],{},"AWS ",[39,233,234],{},"AKIA…"," mais a metade secreta",[135,237,238],{},"Sim, inclusive computação por hora",[135,240,241],{},"Seus buckets S3",[135,243,244],{},"Deactivate, e dá para desfazer",[135,246,247],{},"Não, você pode ter duas chaves ao mesmo tempo",[111,249,250,257,259,262,264],{},[135,251,137,252,46,255],{},[39,253,254],{},"sb_secret_",[39,256,77],{},[135,258,144],{},[135,260,261],{},"Cada linha de cada tabela",[135,263,144],{},[135,265,266],{},"Sim, num projeto antigo",[10,268,269],{},"Duas observações sobre essa tabela, porque as duas mudam o que vem depois.",[10,271,272,273,276,277,279],{},"Uma chave de acesso da AWS são duas sequências de caracteres, um identificador\nque começa com ",[39,274,275],{},"AKIA"," e uma metade secreta, e a AWS exige as duas juntas para\nassinar uma requisição. Ou seja, uma sequência ",[39,278,275],{}," sozinha num bundle não dá\npara usar, e a razão para tratá-la como urgente mesmo assim é que as duas\nmetades quase sempre são coladas juntas. Abra o arquivo e procure a segunda\nantes de decidir em qual caso você está.",[10,281,282,283,287,288,287,292,296,297,301],{},"O detalhe de cada provedor fica com o provedor:\n",[52,284,286],{"href":285},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","uma chave da OpenAI",",\n",[52,289,291],{"href":290},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","uma chave de API do Google",[52,293,295],{"href":294},"\u002Fblog\u002Fstripe-secret-key-in-frontend","uma chave secreta da Stripe"," e\n",[52,298,300],{"href":299},"\u002Fblog\u002Frotate-supabase-service-role-key","uma chave service_role do Supabase",",\nque é a única com um procedimento próprio.",[17,303,305],{"id":304},"parar-a-chave-e-substituir-a-chave-são-dois-botões-diferentes","Parar a chave e substituir a chave são dois botões diferentes",[10,307,308],{},"Todo provedor daquela tabela dá os dois, e o pânico vai no segundo.",[310,311,312,319,338,347],"ul",{},[313,314,315,318],"li",{},[28,316,317],{},"Google."," Restringir uma chave não muda a sequência de caracteres, então seu\naplicativo continua funcionando. A orientação de segurança deles coloca isso\nantes de tudo: \"First try to restrict your API keys\", e rotacionar é a\nterceira opção, para quando uma restrição não é possível.",[313,320,321,324,325,328,329,333,334,337],{},[28,322,323],{},"Stripe."," ",[28,326,327],{},"Expire key"," para uma chave sozinha, sem substituta envolvida. A\nposição deles sobre quando usar isso não tem meio-termo: \"If a restricted or\nsecret API key is exposed or compromised, rotate it immediately even if you\naren't sure anyone saw it.\" Eles também separam as duas palavras que todo\nmundo usa como sinônimo. ",[330,331,332],"em",{},"Exposure"," é a chave ter ficado visível onde não\ndevia. ",[330,335,336],{},"Compromise"," é a prova de que alguém a usou.",[313,339,340,324,343,346],{},[28,341,342],{},"AWS.",[28,344,345],{},"Deactivate"," é o controle, e o útil é que dá para desfazer. A AWS\ndiz para não apagar a chave antiga enquanto você ainda estiver conferindo: \"we\nrecommend that you do not immediately delete the first access key. Instead,\nchoose Actions and then choose Deactivate.\" Se algo que você esqueceu ainda\nprecisar dela, é só ligar de novo.",[313,348,349,352,353,355,356,358,359,362],{},[28,350,351],{},"Supabase, num projeto antigo."," Há uma única chave de desligar, e ela cobre\nas duas chaves legadas. ",[39,354,49],{}," e ",[39,357,77],{}," são assinadas pelo mesmo\nsegredo, então desativar a que você quer matar para também a que o seu\nfrontend usa.\n",[52,360,361],{"href":299},"Os quatro passos que evitam isso","\nvalem mais lidos antes de mexer no interruptor do que depois.",[95,364],{"alt":365,"caption":366,"src":367},"Um painel com dois interruptores. O da esquerda está baixado e desenhado em âmbar, com uma chave riscada ao lado. O da direita está levantado e desenhado em turquesa, com uma chave ao lado e uma seta que leva a uma janela de aplicativo funcionando.","Dois controles, e só o da esquerda fecha o buraco. Em qual você pega primeiro é a decisão de que trata este artigo.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Ftwo-switches-1600x600.png",[17,369,371],{"id":370},"ler-o-log-do-período-em-que-a-chave-esteve-fora","Ler o log do período em que a chave esteve fora",[10,373,374],{},"A janela abre com o deploy que publicou a chave e fecha quando você a parou. É\nesse intervalo de datas que você usa como filtro no log do provedor.",[10,376,377,378,381],{},"Todo provedor da tabela guarda um. A Stripe mostra os logs de requisição de uma\nchave só, pelo menu de três pontos ao lado dessa chave na página de API Keys. A\nAWS coloca uma data de último uso em cada chave de acesso no console do IAM sem\nconfigurar nada, e registra as chamadas em si no CloudTrail. O Google traça o\nuso por chave no Cloud Console, que é também a leitura que a orientação deles\npede antes de você mudar qualquer coisa numa chave. O Supabase guarda logs de\nAPI e de banco de dados do projeto, e\n",[52,379,380],{"href":299},"como estreitar a janela numa chave do Supabase","\ndiz o que procurar neles.",[10,383,384],{},"O que você procura é tráfego que não consegue explicar: requisições a tabelas ou\nendpoints que o seu aplicativo nunca toca, volume em horários em que ninguém\nestava usando, exclusões que ninguém fez. Depois olhe os dados em si, porque uma\nmensagem de suporte sobre um registro que mudou sozinho é como a maioria desses\ncasos é descoberta de fato, e ela chega semanas depois.",[10,386,387],{},"Muitas vezes não dá para ter certeza, e a Stripe diz o mesmo da detecção dela:\n\"Stripe doesn't guarantee detection of all exposed or compromised keys.\" Então\n\"nada no log\" é um resultado, e vale escrever isso com o intervalo de datas ao\nlado.",[17,389,391],{"id":390},"rotacionar-sem-derrubar-o-aplicativo","Rotacionar sem derrubar o aplicativo",[10,393,394],{},"Três dos quatro provedores acima dão uma janela em que a chave antiga e a nova\nfuncionam juntas, e é isso que evita uma queda.",[10,396,397,399,400,403],{},[28,398,323],{}," \"When you rotate a key in the Dashboard, both the old and new keys\nwork for up to 7 days.\" A caixa de diálogo também tem a opção ",[28,401,402],{},"Now",", e a\ndocumentação deles é explícita: se você escolher, a chave antiga é apagada. Esse\né o botão da emergência com medidor, e não o de uma migração tranquila. O\nconselho deles sobre quando soltar a antiga é uma medição, não uma data: confira\nos logs de requisição dela e só a deixe expirar depois que o volume estiver em\nzero por algumas horas ou dias.",[10,405,406,408],{},[28,407,317],{}," Rotacionar cria a chave nova carregando todas as restrições da\nantiga e, nas palavras deles, \"both the old and new key are accepted\" durante a\njanela em que você move seus aplicativos. Se apagar a antiga cedo demais e algo\nquebrar, há um caminho de volta: uma chave de API do Google apagada pode ser\nrestaurada em até 30 dias.",[10,410,411,413],{},[28,412,342],{}," A sequência está na documentação deles e começa pela chave nova: crie a\nsegunda chave de acesso enquanto a primeira ainda está ativa, mova cada\naplicação para ela, confira a data de último uso da antiga, desative, e só então\napague. Um teto para contar: um usuário do IAM pode ter no máximo duas chaves de\nacesso, então uma terceira aplicação ainda numa chave antiga não tem para onde\nir.",[10,415,416,418,419,355,421,423],{},[28,417,351],{}," Sem janela. A rotação direta das chaves\nlegadas ",[39,420,49],{},[39,422,77],{}," não é mais suportada, então invalidar uma delas\né uma migração para o novo par de chaves, e a ordem dos quatro passos é o que\nmantém o aplicativo no ar.",[17,425,427],{"id":426},"ela-continua-no-seu-histórico-do-git","Ela continua no seu histórico do Git",[10,429,430],{},"Continua, e a documentação do GitHub sobre isso começa mandando você para outro\nlugar.",[10,432,433],{},"A página deles sobre remover dados sensíveis devolve você à chave: \"if the\nsensitive data you need to remove is a secret (e.g. password\u002Ftoken\u002Fcredential),\nas is often the case, then as a first step you need to revoke and\u002For rotate that\nsecret\", e depois: \"Once the secret is revoked or rotated, it can no longer be\nused for access, and that may be sufficient to solve your problem. Going through\nthe extra steps to rewrite the history and remove the secret may not be\nwarranted.\"",[10,435,436],{},"A razão que eles dão é o que um force push não alcança. Depois de reescrever o\nseu histórico, os commits antigos continuam lá \"In any clones or forks of your\nrepository\" e \"Directly via their SHA-1 hashes in cached views on GitHub\". O\nsuporte consegue limpar as visualizações em cache e as referências em pull\nrequests se você pedir, e traça o próprio limite: ele \"will only assist in the\nremoval of sensitive data in cases where we determine that the risk can't be\nmitigated by rotating affected credentials.\" Um fork fica com a cópia dele de\nqualquer jeito, e o GitHub não pode dar o contato do dono.",[10,438,439],{},"Então a ordem que eles descrevem é a prática: revogar a chave e depois decidir se\nreescrever o histórico compensa os efeitos colaterais. Revogar alcança cópias\nque uma reescrita não alcança, inclusive a de um clone que você nem sabe que\nexiste e a de um print que alguém guardou.",[95,441],{"alt":442,"caption":443,"src":444},"Três documentos iguais e apagados, um fork, o clone de alguém e uma visualização em cache, cada um ainda segurando a mesma chave âmbar. Uma única linha turquesa cruza a imagem e risca as três chaves.","A mesma chave, em três cópias que você não consegue apagar. Revogá-la risca as três de uma vez.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fone-line-covers-every-copy-1600x520.png",[17,446,448],{"id":447},"como-impedir-que-a-próxima-entre-no-bundle","Como impedir que a próxima entre no bundle",[10,450,451,454],{},[28,452,453],{},"Uma chave entra no seu bundle por um deploy, e os deploys continuam\nacontecendo."," Cada um deles é mais uma chance de um valor que você colocou num\npainel de segredos acabar num arquivo que o navegador baixa. É por isso que uma\nverificação feita no mês passado descreve o aplicativo do mês passado.",[10,456,457],{},[28,458,459,462],{},[52,460,461],{"href":62},"A nossa varredura gratuita"," responde à pergunta que trouxe\nvocê até aqui.",[310,464,465,468,471],{},[313,466,467],{},"as nove verificações contra a sua URL no ar, em uns 20 segundos",[313,469,470],{},"cada chave que ela enxerga de fora, classificada e não apenas encontrada",[313,472,473],{},"uma nota e os achados, sem conta",[10,475,476],{},[28,477,478,482],{},[52,479,481],{"href":480},"\u002Fpricing","O Reeve Monitor"," roda essas verificações de novo sem você pedir.",[310,484,485,488,495,498],{},[313,486,487],{},"as nove verificações a cada hora, em até três aplicativos",[313,489,490,491,494],{},"uma mensagem quando um resultado ",[28,492,493],{},"muda",", para que a chave que saiu no deploy\nde ontem à noite não fique esperando você olhar",[313,496,497],{},"se o aplicativo responde, a cada 60 segundos",[313,499,500],{},"um relatório mensal do que ele viu",[10,502,503],{},[28,504,505,509],{},[52,506,508],{"href":507},"\u002Fsupabase-backups","O Reeve Care"," guarda uma cópia do seu banco de dados\nSupabase, para as chaves que conseguem escrever.",[310,511,512,515,518,521,524],{},[313,513,514],{},"uma cópia criptografada toda noite, guardada onde o seu projeto não alcança",[313,516,517],{},"cada cópia verificada antes de contar, contando as linhas de cada tabela",[313,519,520],{},"uma restauração em um clique quando você precisar",[313,522,523],{},"os seus arquivos enviados também, assim que você conectar uma credencial de\nStorage",[313,525,526],{},"tudo o que o Monitor faz",[10,528,529,530,532,533,537],{},"Uma chave vazada que só consegue ler deixa os seus dados onde estavam. Uma chave\n",[39,531,77],{},", ou uma da AWS com permissão de escrita, consegue esvaziar uma\ntabela, e nenhuma rotação depois traz as linhas de volta.\n",[52,534,536],{"href":535},"\u002Fblog\u002Fai-agent-deleted-my-database","O dia em que um agente de IA apagou um banco de dados de produção","\nmostra como isso é por dentro.",[17,539,541],{"id":540},"o-que-fazer-agora","O que fazer agora",[543,544,545],"key-takeaways",{},[310,546,547,558,561,570,573,576],{},[313,548,549,550,46,552,554,555,557],{},"Identifique a chave antes de mexer nela. Uma chave ",[39,551,49],{},[39,553,45],{}," do Supabase e uma ",[39,556,41],{}," da Stripe estão no lugar certo, e dos 1.332 aplicativos em que encontramos uma chave que merecia aviso, 1.142 tinham uma chave de API do Google, que pede uma restrição em vez de uma rotação.",[313,559,560],{},"Pergunte se ela tem um medidor. Se as requisições de outra pessoa caem na sua fatura, pare a chave agora e deixe a funcionalidade quebrar.",[313,562,563,564,566,567,569],{},"Use tanto o controle que para quanto o que substitui: ",[28,565,327],{}," na Stripe, ",[28,568,345],{}," na AWS, uma restrição por site e por API no Google.",[313,571,572],{},"Substitua depois, dentro da janela do provedor. A Stripe dá sete dias com as duas chaves ativas, o Google aceita as duas enquanto você migra, e a AWS deixa você ter duas chaves de acesso ao mesmo tempo.",[313,574,575],{},"Leia o log do provedor no período entre o deploy e a parada, e anote o que encontrou, inclusive \"nada\".",[313,577,578],{},"Deixe o histórico do Git por último. Depois que a chave está revogada, a própria orientação do GitHub diz que reescrever o histórico pode não valer a pena.",[10,580,581,582,586],{},"Se você preferir percorrer tudo isso como uma lista, o\n",[52,583,585],{"href":584},"\u002Fchecklist","checklist de segurança em 10 minutos"," cobre este assunto e as\noutras coisas que vale desligar num aplicativo recém-lançado.",{"title":588,"searchDepth":589,"depth":589,"links":590},"",3,[591,593,594,595,596,597,598,599,600],{"id":19,"depth":592,"text":20},2,{"id":67,"depth":592,"text":68},{"id":102,"depth":592,"text":103},{"id":304,"depth":592,"text":305},{"id":370,"depth":592,"text":371},{"id":390,"depth":592,"text":391},{"id":426,"depth":592,"text":427},{"id":447,"depth":592,"text":448},{"id":540,"depth":592,"text":541},"Noções de segurança","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcover-1200x630.png","Um cartão de acesso com uma chave desenhada, parado diante de um painel de disjuntores cujo primeiro interruptor está baixado na posição de desligado.","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.",false,"md",[608,610,613,616,619],{"q":68,"a":609},"Descubra se a chave pode gastar dinheiro. Uma chave que cobra por requisição está custando alguma coisa agora mesmo, então pare a chave imediatamente e aceite que a funcionalidade que a usa fique quebrada por alguns minutos. Uma chave que só lê dados já foi lida se estava pública, então use o tempo para fazer a troca numa ordem que não tranque você para fora do seu próprio aplicativo.",{"q":611,"a":612},"Revogar ou rotacionar primeiro?","Revogar primeiro, se a chave tiver um medidor. Parar a chave antiga e emitir uma nova são dois controles separados em todo provedor, e só o primeiro fecha o buraco. A exceção é uma chave que você pode restringir no lugar disso: o Google manda tentar uma restrição por site e por API antes mesmo de rotacionar uma chave de API do Google.",{"q":614,"a":615},"Como sei se alguém usou a minha chave?","Reduza a janela ao período entre o deploy que publicou a chave e o momento em que você a parou, e leia o log do provedor nesse intervalo. A Stripe mostra logs de requisição por chave, a AWS mostra uma data de último uso na chave de acesso e registra as chamadas no CloudTrail, o Google traça o uso por chave, e o Supabase guarda logs de API e de banco de dados. Você procura requisições a coisas que o seu aplicativo nunca toca e tráfego em horários em que ninguém estava usando. Muitas vezes não dá para ter certeza, e esse é um resultado normal.",{"q":617,"a":618},"Rotacionar a chave vai quebrar meu aplicativo?","Normalmente não, se você usar a janela que o provedor dá. A Stripe mantém a chave antiga e a nova funcionando juntas por até sete dias. O Google emite a chave nova com as restrições da antiga e aceita as duas enquanto você migra. A AWS deixa você ter duas chaves de acesso ao mesmo tempo, então a nova já está ativa antes de a antiga sair. A exceção é um projeto antigo do Supabase, onde a chave que desativa as chaves legadas leva junto a chave do seu frontend.",{"q":620,"a":621},"A chave está no meu histórico do Git. Apagar o arquivo basta?","Não, e reescrever o histórico provavelmente também não é a resposta. A documentação do GitHub diz para revogar ou rotacionar o segredo primeiro, e que depois disso entrar na reescrita do histórico pode não valer a pena. Um force push não alcança as cópias em forks e clones, nem as visualizações em cache acessíveis pelo hash do commit. Deixar a chave inútil cobre todas as cópias de uma vez.","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",[624,625,626,627,628,629,630,631],"chave api vazou o que fazer","api key vazada","minha chave api está pública","chave api comprometida","rotacionar chave api vazada","achei minha api key no github","api key exposta no frontend","o que alguém pode fazer com a minha chave api",{},true,"Sua chave de API vazou. O que fazer, em ordem","\u002Fblog\u002Fapi-key-leaked-what-to-do","2026-10-09",{"title":5,"description":604},"blog\u002Fapi-key-leaked-what-to-do",[640,641,642,643],"Se uma chave de API vazou, o que fazer primeiro depende de qual chave é. Chaves publicáveis moram no seu frontend e não precisam de nada.","Se for um segredo de verdade, descubra se a chave pode gastar dinheiro. É a única parte disso com um relógio correndo.","Parar uma chave e substituir uma chave são dois controles diferentes em todo provedor, e quase todos dão uma janela em que as duas chaves funcionam.","Depois leia o log do provedor para o período em que a chave esteve fora, e deixe seu histórico do Git quieto até a chave estar morta.","Ra7swaK2Zq9ZeDqqHY3GF10Jmy4GryhgZ4tZnOaqVP0",[646,652,658,659,665,671,677,683,689,695,701,707,713,719,726,732,738,743,749,755,761,767,773,779,784,790,796,802,808,814,820,826,832,838,844,849,855,861,867,873,878,884,890,896,902,908,914,920,926,932,938,944,949,954,960,965,971,977,983,988,994],{"path":647,"title":648,"description":649,"published":650,"category":601,"image":651,"draft":605},"\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":653,"title":654,"description":655,"published":656,"category":601,"image":657,"draft":605},"\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":635,"title":5,"description":604,"published":636,"category":601,"image":622,"draft":605},{"path":660,"title":661,"description":662,"published":663,"category":601,"image":664,"draft":605},"\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":666,"title":667,"description":668,"published":669,"category":601,"image":670,"draft":605},"\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":672,"title":673,"description":674,"published":675,"category":601,"image":676,"draft":605},"\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":678,"title":679,"description":680,"published":681,"category":601,"image":682,"draft":605},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","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":684,"title":685,"description":686,"published":687,"category":601,"image":688,"draft":605},"\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":690,"title":691,"description":692,"published":693,"category":601,"image":694,"draft":605},"\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":696,"title":697,"description":698,"published":699,"category":601,"image":700,"draft":605},"\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":702,"title":703,"description":704,"published":705,"category":601,"image":706,"draft":605},"\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":708,"title":709,"description":710,"published":711,"category":601,"image":712,"draft":605},"\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":714,"title":715,"description":716,"published":717,"category":601,"image":718,"draft":605},"\u002Fblog\u002Fsupabase-free-plan-limits","Quanto custa o Supabase? Os limites do plano gratuito","Quanto custa o Supabase: o plano gratuito tem 500 MB de banco, 5 GB de egress e nenhum backup. O que acontece em cada limite e o que o Pro de $25 muda.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":720,"title":721,"description":722,"published":723,"category":724,"image":725,"draft":605},"\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","Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":727,"title":728,"description":729,"published":730,"category":724,"image":731,"draft":605},"\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":733,"title":734,"description":735,"published":736,"category":724,"image":737,"draft":605},"\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":739,"title":740,"description":741,"published":736,"category":601,"image":742,"draft":605},"\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":744,"title":745,"description":746,"published":747,"category":601,"image":748,"draft":605},"\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":750,"title":751,"description":752,"published":753,"category":601,"image":754,"draft":605},"\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":756,"title":757,"description":758,"published":759,"category":724,"image":760,"draft":605},"\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":762,"title":763,"description":764,"published":765,"category":601,"image":766,"draft":605},"\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":768,"title":769,"description":770,"published":771,"category":601,"image":772,"draft":605},"\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":774,"title":775,"description":776,"published":777,"category":601,"image":778,"draft":605},"\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":294,"title":780,"description":781,"published":782,"category":601,"image":783,"draft":605},"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":785,"title":786,"description":787,"published":788,"category":601,"image":789,"draft":605},"\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":791,"title":792,"description":793,"published":794,"category":601,"image":795,"draft":605},"\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":797,"title":798,"description":799,"published":800,"category":601,"image":801,"draft":605},"\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":803,"title":804,"description":805,"published":806,"category":601,"image":807,"draft":605},"\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":809,"title":810,"description":811,"published":812,"category":724,"image":813,"draft":605},"\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":815,"title":816,"description":817,"published":818,"category":724,"image":819,"draft":605},"\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":821,"title":822,"description":823,"published":824,"category":724,"image":825,"draft":605},"\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":827,"title":828,"description":829,"published":830,"category":601,"image":831,"draft":605},"\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":833,"title":834,"description":835,"published":836,"category":601,"image":837,"draft":605},"\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":839,"title":840,"description":841,"published":842,"category":601,"image":843,"draft":605},"\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":299,"title":845,"description":846,"published":847,"category":601,"image":848,"draft":605},"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":850,"title":851,"description":852,"published":853,"category":601,"image":854,"draft":605},"\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":856,"title":857,"description":858,"published":859,"category":601,"image":860,"draft":605},"\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":862,"title":863,"description":864,"published":865,"category":601,"image":866,"draft":605},"\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":868,"title":869,"description":870,"published":871,"category":601,"image":872,"draft":605},"\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":285,"title":874,"description":875,"published":876,"category":601,"image":877,"draft":605},"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":879,"title":880,"description":881,"published":882,"category":601,"image":883,"draft":605},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","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":885,"title":886,"description":887,"published":888,"category":724,"image":889,"draft":605},"\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":891,"title":892,"description":893,"published":894,"category":601,"image":895,"draft":605},"\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":897,"title":898,"description":899,"published":900,"category":724,"image":901,"draft":605},"\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":903,"title":904,"description":905,"published":906,"category":601,"image":907,"draft":605},"\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":909,"title":910,"description":911,"published":912,"category":601,"image":913,"draft":605},"\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":915,"title":916,"description":917,"published":918,"category":601,"image":919,"draft":605},"\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":921,"title":922,"description":923,"published":924,"category":601,"image":925,"draft":605},"\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":927,"title":928,"description":929,"published":930,"category":724,"image":931,"draft":605},"\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":933,"title":934,"description":935,"published":936,"category":724,"image":937,"draft":605},"\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":939,"title":940,"description":941,"published":942,"category":601,"image":943,"draft":605},"\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":290,"title":945,"description":946,"published":947,"category":601,"image":948,"draft":605},"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":535,"title":950,"description":951,"published":952,"category":724,"image":953,"draft":605},"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":955,"title":956,"description":957,"published":958,"category":601,"image":959,"draft":605},"\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":961,"title":962,"description":963,"published":958,"category":601,"image":964,"draft":605},"\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":966,"title":967,"description":968,"published":969,"category":601,"image":970,"draft":605},"\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":972,"title":973,"description":974,"published":975,"category":724,"image":976,"draft":605},"\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":978,"title":979,"description":980,"published":981,"category":601,"image":982,"draft":605},"\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":984,"title":985,"description":986,"published":981,"category":724,"image":987,"draft":605},"\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":989,"title":990,"description":991,"published":992,"category":724,"image":993,"draft":605},"\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":54,"title":995,"description":996,"published":992,"category":601,"image":997,"draft":605},"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",1791705963225]