---
title: "Riscos de segurança do vibe coding: 5 falhas reais"
description: "O que falha nas apps de vibe coding, com números de três estudos e cinco falhas de acesso que reproduzi em Supabase local, e como verificar a sua."
url: "https://madsalt.tech/pt/blog/vibe-coding-security-risks/"
author: "Denys Zaichenko"
language: "pt"
published: 2026-10-24
---

# Riscos de segurança do vibe coding: 5 falhas reais

Em resumo

O código que uma IA escreve costuma funcionar. O que falha é quem consegue chegar aos dados. Numa auditoria de 2026 a 200 apps de vibe coding já em produção, 91% tinham pelo menos uma vulnerabilidade e o controlo de acesso quebrado foi o maior grupo. Reproduzi cinco dessas falhas numa stack local do Supabase: só com a chave pública, uma tabela sem RLS, uma política sempre verdadeira, uma vista e uma secret key divulgada devolveram cada uma as 3 linhas de 3. Verifique primeiro estes pontos na sua app.

Sou o Denys, engenheiro full-stack e de IA. Corrijo apps que foram feitas com Lovable, Bolt, Cursor ou Claude Code, e a maioria corre em Supabase. Este artigo junta o que a investigação publicada diz sobre a segurança do vibe coding e o que vi ao reconstruir de propósito os erros mais comuns.

## Quais são os riscos de segurança do vibe coding?

O risco principal é o controlo de acesso quebrado: dados que qualquer visitante pode ler ou alterar porque a regra que o devia impedir falta, é demasiado permissiva ou é contornada. Seguem-se a injeção e a autenticação fraca. Três estudos independentes apontam no mesmo sentido:

| Estudo                                                                                                                                  | O que foi testado                                                                    | O que encontrou                                                                                                                                                                                      |
| --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Deng, Fan e Meng, arXiv 2606.23130](https://arxiv.org/abs/2606.23130), junho de 2026                                                   | 200 apps em produção feitas com Claude Code e Lovable, auditadas à mão e com agentes | 182 de 200 apps (91%) tinham pelo menos uma vulnerabilidade; 65,77% dos 1186 achados eram críticos ou altos; o controlo de acesso quebrado foi a maior categoria, em 64% das apps                    |
| [Escape](https://escape.tech/blog/methodology-how-we-discovered-vulnerabilities-apps-built-with-vibe-coding/), outubro de 2025          | 5600 apps públicas do Lovable, Base44, Create.xyz e outras, com uma análise passiva  | Mais de 2000 vulnerabilidades de alto impacto, mais de 400 segredos expostos, 175 casos de dados pessoais expostos; a causa principal foram permissões mal configuradas, sobretudo o RLS do Supabase |
| [Veracode GenAI Code Security Report](https://www.veracode.com/resources/analyst-reports/2026-genai-code-security-report/), 2025 e 2026 | 80 tarefas de programação dadas a mais de 100 modelos                                | Só 55% das tarefas produziram código seguro em 2025; a taxa média de aprovação foi de 56% em 2026, sem alteração conforme o tamanho do modelo ou o ano                                               |

Os estudos medem coisas diferentes, por isso as percentagens não somam um só número. O que partilham é a forma: o código funciona e as falhas estão na fronteira de confiança.

## Que falhas reproduzi?

Montei uma tabela, `orders`, com três linhas de clientes falsos numa stack local do Supabase (CLI 2.109.1, Postgres 17.6, PostgREST 14.14). Depois chamei a Data API como o faz um browser, com a publishable key (chave publicável) que todo o frontend do Supabase leva, e mudei uma só coisa de cada vez.

![O que uma chave pública obteve de uma tabela. Supabase local, 3 linhas de encomendas falsas, um pedido cada. Tabela sem RLS: Publishable key → orders, sem RLS → 3 de 3 linhas; RLS ligado, ainda sem política: Publishable key → orders, com RLS → 0 linhas; Política using (true): Publishable key → using (true) → 3 de 3 linhas; Vista sem security_invoker: Publishable key → vista order_summary → 3 de 3 linhas; Secret key no código do browser: Secret key → BYPASSRLS → 3 de 3 linhas.](https://madsalt.tech/charts/pt/vibe-coding-security-risks.svg)

*Figura 1. A minha reprodução numa stack local do Supabase (Postgres 17.6, PostgREST 14.14), 23 de outubro de 2026.*

| Configuração                     | O que a chave pública obteve                    | Porquê                                                                                                    |
| -------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Tabela sem RLS                   | As 3 linhas, e um insert devolveu `201 Created` | Os grants por omissão deixam o `anon` ler e escrever, e nada filtra as linhas                             |
| RLS ligado, sem política         | `[]`, uma lista vazia                           | O RLS sem nenhuma política nega tudo a `anon` e `authenticated`                                           |
| Política `using (true)`          | As 3 linhas                                     | A política existe, por isso a tabela parece protegida, mas permite todas as linhas                        |
| Vista sobre a tabela protegida   | As 3 linhas                                     | Uma vista corre com os direitos do seu dono, a não ser que tenha `security_invoker = true`; com ele, `[]` |
| Secret key no código do frontend | As 3 linhas                                     | A secret key corresponde a `service_role`, que tem `BYPASSRLS`                                            |

A segunda linha é o momento perigoso. O RLS está ligado e a app mostra uma lista vazia, por isso parece avariada. O prompt mais rápido que a "corrige" é uma política que permite tudo, que é a terceira linha. Esse ciclo, erro e depois uma correção que alarga o acesso, é o padrão que mais encontro em apps de vibe coding, e é por isso que "o RLS está ligado" diz pouco por si só.

## Porque é que o código escrito por IA falha no controlo de acesso?

Um agente é recompensado por código que corre. Uma lista vazia ou um `401` parecem um bug, e a correção que os faz desaparecer é muitas vezes a que abre o acesso. O estudo do arXiv rastreia os seus 1186 achados até oito modos de falha recorrentes, agrupados como defeitos de memória, de objetivo e de conhecimento dos agentes, e concluiu que melhorar os prompts reduziu o número de falhas mas não as eliminou.

A segunda razão é a arquitetura. Uma app do Lovable ou do Bolt costuma não ter um backend próprio: o browser fala diretamente com a base de dados através da Data API. Todas as regras que protegem os dados dos clientes têm de viver no Postgres, como grants, políticas e funções, e nada disso se vê na pré-visualização da app, onde você tem a sessão iniciada como dono. O Supabase está a mudar aqui um valor por omissão: a partir de [30 de outubro de 2026](https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically), as tabelas novas dos projetos existentes deixam de ser concedidas automaticamente à Data API. Na minha stack, uma tabela sem o grant respondeu `42501 permission denied` com uma dica que nomeia o `GRANT` em falta. Isso trava a primeira linha da tabela acima para as tabelas novas, mas não as outras quatro, nem as tabelas que já existem.

## O que mais falha fora da base de dados?

Os mesmos estudos listam riscos que nada têm a ver com o RLS:

- **Segredos no bundle.** A Escape encontrou mais de 400 segredos expostos, incluindo chaves da OpenAI e chaves de administração de pagamentos. Tudo o que é enviado para o browser é público.
- **Guardas de rota só no React.** Uma página que redireciona os utilizadores sem sessão continua a ter por trás uma API que responde a qualquer pessoa.
- **Limites de pedidos que nunca disparam.** Num projeto Supabase alojado que testei, um contador guardado na memória de uma edge function era reposto a cada pedido. Escrevi sobre isso na minha [lista de segurança para apps Lovable](https://madsalt.tech/pt/blog/lovable-app-security-checklist/).
- **Bibliotecas antigas.** A Escape contou 254 instâncias de bibliotecas JavaScript vulneráveis em recursos públicos, muitas vezes herdadas de templates.

## Como se verifica uma app feita com vibe coding?

1. Abra a app, abra o DevTools → Network e procure pedidos a `/rest/v1/`. Copie um como cURL, retire o cabeçalho `Authorization`, mantenha o `apikey` e execute-o. Se vierem dados, vêm também para qualquer pessoa.
2. Procure `sb_secret_` e `service_role` no JavaScript compilado. Uma correspondência é uma chave a rodar hoje.
3. Execute a [Auditoria de segurança Supabase](https://madsalt.tech/pt/tools/supabase-security-check/) gratuita. Lê o catálogo do projeto e assinala, entre as suas 46 regras, "RLS desativado em tabelas expostas", "Políticas que permitem todas as linhas", "Vistas que contornam o RLS" e "Privilégios por omissão que abrem novos objetos à API": as quatro primeiras linhas da tabela acima.
4. Teste com dois utilizadores de duas empresas, o único teste que um scanner não pode fazer por si. Como o faço está na [lista para Lovable](https://madsalt.tech/pt/blog/lovable-app-security-checklist/), e [como testar o Supabase RLS](https://madsalt.tech/pt/blog/how-to-test-supabase-rls/) mostra o método numa app em produção com um ecrã de permissões.

```bash
curl 'https://<project>.supabase.co/rest/v1/orders?select=*' \
  -H 'apikey: <the publishable key from your page>'
```

## O que isto não mostra

A minha reprodução é uma tabela numa stack local, montada para mostrar cada mecanismo, não uma análise de apps reais. Os números de prevalência vêm dos três estudos, cada um com a sua amostra e o seu método, ligados acima. E um resultado limpo nestas cinco verificações não torna uma app segura: bugs de lógica, como uma guarda que deixa passar um valor em falta, precisam dos seus próprios testes. Um deles está em [um NULL que saltou uma verificação de permissões](https://madsalt.tech/pt/notes/plpgsql-if-not-null-fails-open/).

Fez a sua app com uma ferramenta de IA?

Gostava de trocar impressões sobre o que verificar primeiro. Sem pitch.

[Fale comigo](https://madsalt.tech/pt/#contact)
