[{"data":1,"prerenderedAt":663},["ShallowReactive",2],{"blog-pt-missing-security-headers":3,"blog-index-pt":418},{"id":4,"title":5,"body":6,"category":374,"cover":375,"coverAlt":376,"description":377,"draft":378,"extension":379,"faq":380,"image":396,"keywords":397,"meta":405,"navigation":406,"ogTitle":407,"path":408,"published":409,"seo":410,"stem":411,"tldr":412,"updated":409,"__hash__":417},"blog_pt\u002Fblog\u002Fmissing-security-headers.md","Cabeçalhos de segurança faltando: quando isso importa",{"type":7,"value":8,"toc":362},"minimark",[9,13,21,30,35,38,41,44,47,51,54,57,63,70,73,76,83,87,90,179,192,196,199,202,207,210,215,227,231,234,237,252,261,265,268,283,293,296,308,312,349],[10,11,12],"p",{},"Seu scan volta e quase todas as linhas estão verdes. Uma está âmbar: alguns\ncabeçalhos de segurança do navegador estão faltando. É a única coisa colorida da\npágina, então parece a primeira de que cuidar.",[10,14,15,16,20],{},"Aqui está a parte que a maioria dos conselhos sobre isso erra. ",[17,18,19],"strong",{},"Cabeçalhos de\nsegurança faltando é o achado que mais imprimimos e, sozinho, ele quase não diz\nnada sobre alguém conseguir chegar aos seus dados."," Tratar isso como uma\ninvasão significa ou corrigir no susto, na frente das coisas que de fato decidem\nquem lê o seu banco de dados, ou aprender que linhas âmbar são ruído, o que é\npior.",[10,22,23,24,29],{},"Entre 12 e 14 de agosto de 2026 rodamos as mesmas nove verificações externas em\n30.998 apps no ar feitos com Lovable, Bolt, v0, Replit e Base44. Dos apps em que\nessa verificação obteve resposta, 30.756 de 30.981 estavam sem pelo menos um\ncabeçalho. Os números completos estão no\n",[25,26,28],"a",{"href":27},"\u002Fresearch\u002Fvibe-coded-app-security-2026","nosso relatório de varredura",".",[31,32,34],"h2",{"id":33},"cabeçalhos-de-segurança-faltando-são-um-problema","Cabeçalhos de segurança faltando são um problema?",[10,36,37],{},"É uma lacuna real e quase sempre a linha menos urgente do seu relatório.",[10,39,40],{},"Um cabeçalho de segurança é uma instrução curta que o seu servidor anexa a cada\npágina que envia, endereçada ao navegador de quem visita e não à pessoa. Não\ndeixe outro site colocar esta página dentro de um quadro. Não adivinhe que tipo\nde arquivo é este. Não passe o meu endereço completo quando alguém clicar para\nfora. São bilhetes para um ajudante que faz o que qualquer site mandar.",[10,42,43],{},"O resto do seu relatório é sobre fechaduras. Se o Row Level Security está\nligado, se tem uma chave secreta no seu código, se um bucket de armazenamento\nlista o conteúdo: é isso que decide quem consegue chegar aos seus dados. Bilhete\ne fechadura a gente quer os dois, e o bilhete que você nunca escreveu não é o\nmotivo pelo qual se perde um banco de dados.",[10,45,46],{},"Nossa nota trata assim. Um cabeçalho faltando tira cinco pontos de cem e não\nlimita o teto, então um app cujo único achado é esse sai com 95 e nota A.",[31,48,50],{"id":49},"o-que-encontramos-em-30998-apps","O que encontramos em 30.998 apps",[10,52,53],{},"Cabeçalhos faltando apareceram em quase tudo, e mal se mexeram junto com o resto\ndo relatório.",[10,55,56],{},"25.821 desses apps obtiveram resposta das nove verificações, e é esse o grupo em\nque \"não tinha mais nada\" significa alguma coisa. Entre eles, 25.606 estavam sem\npelo menos um cabeçalho e 215 tinham os cinco.",[58,59],"diagram",{"alt":60,"caption":61,"src":62},"Uma grade com quatro números. As linhas são o achado sobre cabeçalhos, desenhado como uma barra cheia quando presente e uma barra vazia tracejada quando falta. As colunas são o resto do relatório, um tique para nada encontrado e um xis para algo encontrado. Linha de cima: 70 e 145. Linha de baixo: 17.043 e 8.563.","Apps sem cabeçalhos não tinham mais chance de ter outra coisa errada do que apps que tinham os cinco.","\u002Fblog\u002Fmissing-security-headers\u002Fdoes-it-predict-anything-1600x900.png",[10,64,65,66,69],{},"Dos 25.606 apps sem pelo menos um cabeçalho, ",[17,67,68],{},"17.043 não tinham mais nada de\nerrado",". Dois em cada três. Era o único problema do relatório deles.",[10,71,72],{},"Agora leia a outra linha, que é a parte que nos surpreendeu. Dos 215 apps que\ntinham os cinco cabeçalhos definidos, 145 tinham outra coisa errada. Essa é uma\ntaxa de problemas reais mais alta do que entre os apps sem cabeçalhos, e não\nmais baixa.",[10,74,75],{},"Não medimos o porquê, e a leitura honesta é estreita: seja lá o que essas\nvarreduras encontraram, o achado sobre cabeçalhos não previu isso. Um app com um\nconjunto perfeito de cabeçalhos não era um app mais seguro nos nossos dados. A\nexplicação mais provável é que definir cabeçalhos já significa que alguém\nconfigurou uma hospedagem de verdade, o que costuma significar um app maior com\nmais coisa para dar errado, mas isso é um palpite e não testamos.",[10,77,78,79,29],{},"Se você quiser ver quais dessas linhas o seu próprio app produz, o scan é\ngratuito, leva uns 20 segundos e não precisa de conta:\n",[25,80,82],{"href":81},"\u002Fsecurity-scanner","escaneie seu app",[31,84,86],{"id":85},"o-que-cada-cabeçalho-realmente-faz","O que cada cabeçalho realmente faz",[10,88,89],{},"Cada um desliga um comportamento do navegador que vem ligado de fábrica.",[91,92,93,109],"table",{},[94,95,96],"thead",{},[97,98,99,103,106],"tr",{},[100,101,102],"th",{},"Cabeçalho",[100,104,105],{},"O que ele diz ao navegador",[100,107,108],{},"O que a ausência dele permite",[110,111,112,127,140,153,166],"tbody",{},[97,113,114,121,124],{},[115,116,117],"td",{},[118,119,120],"code",{},"Content-Security-Policy",[115,122,123],{},"De quais lugares esta página pode carregar código e estilos",[115,125,126],{},"Um script injetado consegue mandar dados para onde quiser",[97,128,129,134,137],{},[115,130,131],{},[118,132,133],{},"Strict-Transport-Security",[115,135,136],{},"Volte sempre por HTTPS, nunca por HTTP puro",[115,138,139],{},"Uma visita numa rede não confiável pode ser empurrada para HTTP puro",[97,141,142,147,150],{},[115,143,144],{},[118,145,146],{},"X-Frame-Options",[115,148,149],{},"Não deixe outro site exibir esta página dentro de um quadro",[115,151,152],{},"Sua página pode ser carregada invisível dentro da de outra pessoa",[97,154,155,160,163],{},[115,156,157],{},[118,158,159],{},"X-Content-Type-Options",[115,161,162],{},"Confie no tipo de arquivo que eu passei e não adivinhe pelo conteúdo",[115,164,165],{},"Um arquivo que alguém subiu pode ser servido como um tipo de arquivo diferente",[97,167,168,173,176],{},[115,169,170],{},[118,171,172],{},"Referrer-Policy",[115,174,175],{},"Quanto deste endereço repassar quando alguém clicar para fora",[115,177,178],{},"URLs completas, com tudo que houver nelas, chegam a servidores de terceiros",[10,180,181,182,184,185,188,189,191],{},"Dois deles se sobrepõem, e o scanner leva isso em conta. Uma\n",[118,183,120],{}," que contenha ",[118,186,187],{},"frame-ancestors"," faz o mesmo trabalho de\n",[118,190,146],{},", então a nossa verificação conta qualquer um dos dois e não\nexige os dois.",[31,193,195],{"id":194},"quando-um-cabeçalho-faltando-é-o-problema-inteiro","Quando um cabeçalho faltando é o problema inteiro",[10,197,198],{},"Quando o seu app tem algo que vale a pena clicar enquanto a pessoa está logada.",[10,200,201],{},"Esse é o caso do clickjacking, e é o único que funciona sem nenhum outro erro.\nAlguém carrega o seu app num quadro invisível dentro de uma página que controla\ne põe os botões dele por cima dos seus, de modo que quem já está logado clica no\nque parece a página dele e acerta um controle seu: o botão que apaga uma conta,\naprova uma transferência ou troca um endereço de e-mail.",[58,203],{"alt":204,"caption":205,"src":206},"Duas fileiras. Na primeira, uma página viaja para a direita e uma barra a detém antes de chegar a um painel vazio e tracejado. Na segunda não há barra, e a página aparece desenhada pequena dentro do outro painel, com um ponteiro do mouse em cima do botão dela.","Com o cabeçalho, o navegador se recusa a desenhar a sua página dentro de outro site. Sem ele, isso é uma coisa perfeitamente prevista.","\u002Fblog\u002Fmissing-security-headers\u002Floaded-inside-another-page-1600x790.png",[10,208,209],{},"Quem visita está logado, então a ação carrega a sessão dessa pessoa. Nada no seu\nbanco de dados precisa estar mal configurado. O que faz isso funcionar é que\nnunca disseram ao navegador para recusar.",[10,211,212,214],{},[118,213,172],{}," tem uma versão menor do mesmo formato. Se uma página sua com\nsessão aberta carrega algo identificável na URL e aponta para um servidor de\nimagens ou um script de analytics, o endereço inteiro viaja junto com o clique.\nQuem opera aquele outro servidor vê onde o seu usuário estava.",[10,216,217,218,220,221,223,224,226],{},"Os outros três são condicionais. Eles importam quando outra coisa já deu errado,\ne o trabalho deles é manter isso pequeno. Uma ",[118,219,120],{}," limita o\nque um script injetado consegue fazer com o acesso que tem.\n",[118,222,159],{}," importa se estranhos podem subir arquivos para você.\n",[118,225,133],{}," cobre quem usa o seu app numa rede que não controla.",[31,228,230],{"id":229},"eu-preciso-de-cabeçalhos-de-segurança","Eu preciso de cabeçalhos de segurança?",[10,232,233],{},"Precisa. Eles são baratos, e vêm depois dos achados que decidem quem pode ler o\nseu banco de dados.",[10,235,236],{},"A ordem que sai da medição acima: primeiro tudo que estiver como crítico ou alto\nno seu relatório, cabeçalhos depois. Se o seu relatório tem só essa linha, como\nfoi o caso de 17.043 dos apps que escaneamos, então os cabeçalhos ficam no topo\nda sua lista por eliminação.",[10,238,239,240,243,244,247,248,251],{},"Dois dos cinco não custam nada para acertar.\n",[118,241,242],{},"X-Content-Type-Options: nosniff"," e\n",[118,245,246],{},"Referrer-Policy: strict-origin-when-cross-origin"," são uma linha cada, não têm\nvalor errado a escolher e não conseguem quebrar um app que funciona.\n",[118,249,250],{},"X-Frame-Options: DENY"," também é uma linha, e vale olhar antes se você embute o\nseu próprio app em algum lugar de propósito.",[10,253,254,256,257,260],{},[118,255,120],{}," é o que dá trabalho de verdade. Uma primeira tentativa\ncostuma bloquear algo de que a sua própria página precisava, e o sintoma é uma\nfunção que para de funcionar sem avisar. Suba como\n",[118,258,259],{},"Content-Security-Policy-Report-Only",", que conta o que teria bloqueado sem\nbloquear nada, e leia uma semana de relatórios antes de ligar.",[31,262,264],{"id":263},"como-adicioná-los","Como adicioná-los",[10,266,267],{},"Naquilo que de fato serve o seu app para a internet, que muitas vezes não é o\nlugar onde você o constrói.",[10,269,270,271,274,275,278,279,282],{},"A maioria dos builders publica numa hospedagem que é dona da resposta, então a\nconfiguração mora lá. Na Vercel é ",[118,272,273],{},"headers"," dentro do ",[118,276,277],{},"vercel.json",". No Netlify\ne no Cloudflare Pages é um arquivo ",[118,280,281],{},"_headers"," na raiz do que você publica. Atrás\ndo proxy da Cloudflare é uma Transform Rule. Se você roda um servidor próprio, é\na sua configuração de nginx ou Caddy.",[284,285,287],"callout",{"type":286},"warn",[10,288,289,292],{},[17,290,291],{},"Se o seu app está no subdomínio do próprio builder, pode ser que você não\nconsiga defini-los de jeito nenhum."," A plataforma manda a resposta, os\ncabeçalhos são escolha dela, e não existe arquivo que você possa adicionar para\nsobrepor. Essa é uma resposta real, não falta de procurar direito. Conectar um\ndomínio próprio é o que dá a você uma hospedagem para configurar e, enquanto\nvocê não quiser uma, esse achado pode ficar tranquilamente no seu relatório.",[10,294,295],{},"O que dá para saber sobre cabeçalhos depois de defini-los é que eles saem sem\nninguém encostar neles. Mudar para um domínio próprio, colocar um proxy na\nfrente, trocar de hospedagem, mexer numa configuração de framework: os\ncabeçalhos que você adicionou moram em um desses lugares, e qualquer um desses\npassos pode deixá-los para trás. Nada te avisa. A página continua funcionando e\na configuração sumiu.",[10,297,298,299,303,304,29],{},"É para esse tipo de coisa que existe o ",[25,300,302],{"href":301},"\u002F#pricing","Reeve Monitor",". Ele roda a\nverificação completa de novo a cada hora em até três apps, acompanha a\ndisponibilidade a cada 60 segundos e te avisa quando um resultado muda, em vez\nde esperar você olhar. O Monitor só acompanha, então se você também quiser uma\ncópia do seu banco de dados em algum lugar que o seu builder não alcance,\n",[25,305,307],{"href":306},"\u002Fsupabase-backups","isso é o Care, e ele cobre o Supabase",[31,309,311],{"id":310},"o-que-fazer-agora","O que fazer agora",[313,314,315],"key-takeaways",{},[316,317,318,322,331,337,343,346],"ul",{},[319,320,321],"li",{},"Leia primeiro o resto do relatório. Se tiver algo marcado como crítico ou alto, o trabalho é esse, e os cabeçalhos esperam.",[319,323,324,325,327,328,330],{},"Coloque hoje ",[118,326,242],{}," e ",[118,329,246],{},". Uma linha cada, nada a decidir, nada a quebrar.",[319,332,333,334,336],{},"Coloque ",[118,335,250],{}," se as pessoas fazem login no seu app e conseguem fazer algo pesado com um clique.",[319,338,339,340,342],{},"Deixe ",[118,341,120],{}," por último e comece em modo report-only, para descobrir antes dos seus visitantes o que ele quebra.",[319,344,345],{},"Se você está num subdomínio de builder sem configuração de cabeçalhos, deixe o achado quieto. Ele ainda não é seu.",[319,347,348],{},"Confira de novo depois de mudar de domínio, adicionar um proxy ou trocar de hospedagem. É aí que eles somem.",[10,350,351,352,356,357,361],{},"Cabeçalhos valem uma tarde tranquila quando o resto do relatório estiver limpo.\nSe você prefere percorrer a lista inteira em ordem, a\n",[25,353,355],{"href":354},"\u002Fchecklist","checklist de segurança de 10 minutos"," cobre o que desligar num app\nrecém-lançado, e\n",[25,358,360],{"href":359},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","os achados que de fato decidem quem lê o seu banco de dados","\nsão os primeiros a tirar do caminho.",{"title":363,"searchDepth":364,"depth":364,"links":365},"",3,[366,368,369,370,371,372,373],{"id":33,"depth":367,"text":34},2,{"id":49,"depth":367,"text":50},{"id":85,"depth":367,"text":86},{"id":194,"depth":367,"text":195},{"id":229,"depth":367,"text":230},{"id":263,"depth":367,"text":264},{"id":310,"depth":367,"text":311},"Noções de segurança","\u002Fblog\u002Fmissing-security-headers\u002Fcover-1200x630.png","A lista de cabeçalhos que um site devolve com cada página, com quatro de suas linhas apenas riscadas e vazias onde entraria um valor.","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.",false,"md",[381,384,387,390,393],{"q":382,"a":383},"Meu scan diz que estão faltando cabeçalhos de segurança. Meu app foi hackeado?","Não. Um cabeçalho faltando é uma configuração que nunca foi ligada, e não é prova de que algo aconteceu. Nada no achado envolve alguém chegando aos seus dados ou à sua conta. Ele descreve uma instrução que o seu site poderia estar dando aos navegadores que o visitam e no momento não dá.",{"q":385,"a":386},"Qual cabeçalho de segurança eu devo colocar primeiro?","X-Content-Type-Options e Referrer-Policy, porque os dois são uma linha só, nenhum tem um valor errado a escolher e nenhum consegue quebrar um app que funciona. Depois X-Frame-Options, se as pessoas fazem login no seu app. Depois Strict-Transport-Security. Content-Security-Policy por último, porque é o único dos cinco que exige pensar de verdade e o único que pode impedir os seus próprios scripts de rodar.",{"q":388,"a":389},"Estou no domínio padrão do meu builder e não existe configuração de cabeçalhos. E agora?","Deixe como está. Quando o seu app é servido a partir de um subdomínio da plataforma, os cabeçalhos de resposta são escolha da plataforma e não sua, e não existe arquivo que você possa adicionar para mudá-los. Conecte um domínio próprio se quiser controle sobre isso, porque é o domínio que permite colocar uma hospedagem sua ou um proxy na frente do app. Até lá, gaste o esforço nos achados que cabe a você corrigir.",{"q":391,"a":392},"Uma Content-Security-Policy pode quebrar o meu app?","Pode, e esse é o resultado normal de uma primeira tentativa. Uma política que não permite scripts inline vai parar os scripts inline, inclusive os que o seu builder gerou, e a página fica em branco ou perde uma função, com um erro que só aparece no console do navegador. Comece com Content-Security-Policy-Report-Only, que relata o que teria bloqueado sem bloquear nada, e leia os relatórios por uma semana antes de ligar de verdade.",{"q":394,"a":395},"Cabeçalhos de segurança ajudam se o meu banco de dados pode ser lido por qualquer um?","Não. Cabeçalhos são instruções para os navegadores que visitam o seu site, e quem lê o seu banco de dados direto não está usando navegador nem visitando o seu site. Essa requisição vai direto para o seu provedor de banco de dados e nunca toca nas suas páginas, então nenhum cabeçalho colocado nelas se aplica a ela. Quem decide essa é o Row Level Security.","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",[398,399,400,401,402,403,404],"cabeçalhos de segurança faltando","content-security-policy faltando","x-frame-options faltando","preciso de cabeçalhos de segurança","verificar cabeçalhos de segurança","strict-transport-security faltando","cabeçalhos de segurança faltando é problema",{},true,"Cabeçalhos de segurança faltando: quando importa?","\u002Fblog\u002Fmissing-security-headers","2026-09-04",{"title":5,"description":377},"blog\u002Fmissing-security-headers",[413,414,415,416],"Cabeçalhos de segurança faltando é o achado mais comum que existe e, sozinho, ele quase não diz nada sobre alguém conseguir chegar aos seus dados.","Escaneamos 30.998 apps no ar. Dois em cada três dos que estavam sem cabeçalhos não tinham mais nada de errado.","Ainda assim vale corrigir, e isso vem depois das coisas que decidem quem pode ler o seu banco de dados.","Em alguns domínios de builders você não consegue defini-los, e deixar como está é uma resposta razoável.","TjuMqX9mwuVuMZwRIyk3rWRaNawMGTP1KnZJ1yhqh_E",[419,426,432,438,444,450,456,462,468,474,480,486,492,498,504,510,516,522,528,534,535,541,547,553,559,565,571,577,583,589,595,601,607,613,619,624,629,635,641,647,652,658],{"path":420,"title":421,"description":422,"published":423,"category":424,"image":425,"draft":378},"\u002Fblog\u002Fsupabase-backup-auth-users","Por que seu dump do Supabase não tem usuários dentro","Rode supabase db dump sozinho e você recebe a forma do seu banco e nenhuma das linhas dele, sem o schema auth onde seus usuários moram.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":427,"title":428,"description":429,"published":430,"category":374,"image":431,"draft":378},"\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":433,"title":434,"description":435,"published":436,"category":374,"image":437,"draft":378},"\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":439,"title":440,"description":441,"published":442,"category":374,"image":443,"draft":378},"\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":445,"title":446,"description":447,"published":448,"category":374,"image":449,"draft":378},"\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":451,"title":452,"description":453,"published":454,"category":374,"image":455,"draft":378},"\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":457,"title":458,"description":459,"published":460,"category":374,"image":461,"draft":378},"\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":463,"title":464,"description":465,"published":466,"category":374,"image":467,"draft":378},"\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":469,"title":470,"description":471,"published":472,"category":374,"image":473,"draft":378},"\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":475,"title":476,"description":477,"published":478,"category":424,"image":479,"draft":378},"\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":481,"title":482,"description":483,"published":484,"category":424,"image":485,"draft":378},"\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":487,"title":488,"description":489,"published":490,"category":424,"image":491,"draft":378},"\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":493,"title":494,"description":495,"published":496,"category":374,"image":497,"draft":378},"\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":499,"title":500,"description":501,"published":502,"category":374,"image":503,"draft":378},"\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":505,"title":506,"description":507,"published":508,"category":374,"image":509,"draft":378},"\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":511,"title":512,"description":513,"published":514,"category":374,"image":515,"draft":378},"\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":517,"title":518,"description":519,"published":520,"category":374,"image":521,"draft":378},"\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":523,"title":524,"description":525,"published":526,"category":374,"image":527,"draft":378},"\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":529,"title":530,"description":531,"published":532,"category":374,"image":533,"draft":378},"\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":408,"title":5,"description":377,"published":409,"category":374,"image":396,"draft":378},{"path":536,"title":537,"description":538,"published":539,"category":374,"image":540,"draft":378},"\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":542,"title":543,"description":544,"published":545,"category":374,"image":546,"draft":378},"\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":548,"title":549,"description":550,"published":551,"category":424,"image":552,"draft":378},"\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":554,"title":555,"description":556,"published":557,"category":374,"image":558,"draft":378},"\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":560,"title":561,"description":562,"published":563,"category":424,"image":564,"draft":378},"\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":566,"title":567,"description":568,"published":569,"category":374,"image":570,"draft":378},"\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":572,"title":573,"description":574,"published":575,"category":374,"image":576,"draft":378},"\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":578,"title":579,"description":580,"published":581,"category":374,"image":582,"draft":378},"\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":584,"title":585,"description":586,"published":587,"category":374,"image":588,"draft":378},"\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":590,"title":591,"description":592,"published":593,"category":424,"image":594,"draft":378},"\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":596,"title":597,"description":598,"published":599,"category":424,"image":600,"draft":378},"\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":602,"title":603,"description":604,"published":605,"category":374,"image":606,"draft":378},"\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":608,"title":609,"description":610,"published":611,"category":374,"image":612,"draft":378},"\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":614,"title":615,"description":616,"published":617,"category":424,"image":618,"draft":378},"\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":359,"title":620,"description":621,"published":622,"category":374,"image":623,"draft":378},"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":625,"title":626,"description":627,"published":622,"category":374,"image":628,"draft":378},"\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":630,"title":631,"description":632,"published":633,"category":374,"image":634,"draft":378},"\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":636,"title":637,"description":638,"published":639,"category":424,"image":640,"draft":378},"\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":642,"title":643,"description":644,"published":645,"category":374,"image":646,"draft":378},"\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":648,"title":649,"description":650,"published":645,"category":424,"image":651,"draft":378},"\u002Fblog\u002Fversion-history-is-not-a-backup","O histórico de versões não é backup. Ele não desfaz um delete.","Lovable e Bolt guardam um histórico de versões do seu código. Seu banco de dados é um serviço à parte, e voltar atrás não traz os seus dados de volta.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":653,"title":654,"description":655,"published":656,"category":424,"image":657,"draft":378},"\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":659,"title":660,"description":661,"published":656,"category":374,"image":662,"draft":378},"\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",1790150955883]