Pular para o conteúdo

Uma equipe editorial e uma comunidade que criam com IA

← Vibecoding

Vibecoding · · 7 min de leitura

Código gerado por IA é seguro? Vibecoding e segurança

Código de IA não é seguro nem inseguro: é código não verificado. As classes de risco reais e um checklist.

A resposta curta para o título: código de IA não é seguro nem inseguro, ele é não verificado. Um modelo de linguagem gera o que é estatisticamente mais provável, não o que é mais seguro. A diferença continua sutil até o momento em que o seu endpoint vai para a internet com uma chave hardcoded ou uma query SQL montada com strings concatenadas. O vibecoding não cria novas classes de vulnerabilidade. Ele apenas as acelera, e é exatamente esse o ponto.

Por que estamos falando disso

Nos últimos dois anos, o perfil de quem coloca código em produção mudou. Antes, “vou subir para prod” significava alguém que já tinha passado por code review, sabia a diferença entre GET e POST e entendia por que nunca se deve confiar no input do usuário. Hoje, o mesmo deploy é feito por alguém que pediu a um agente para “adicionar login” e colou o resultado. O código roda, a demo passa, o cliente fica feliz. A vulnerabilidade é invisível porque nada está pegando fogo, até que alguém vá procurar.

Este não é um texto contra a IA. Escrevo a maior parte do meu próprio código com um assistente e não voltaria para um editor sem ele. Mas tratar código gerado como pronto para deploy é um erro de categoria. É o primeiro rascunho de um júnior muito rápido, não uma auditoria de segurança. O que está em jogo é real: o vazamento do banco de dados de clientes, uma conta sequestrada, uma multa do GDPR. E a questão não é se você sabe programar, mas se alguém revisou a segurança do código antes de ele sair para o mundo.

Classes de risco reais, não teóricas

Vamos deixar as abstrações de lado. Isto é o que realmente sai dos modelos quando você pede “código que funcione”, em ordem de frequência com que eu vejo na prática:

  • Segredos no código. Chaves de API, senhas de banco de dados, tokens: colocados direto em um arquivo “como exemplo”, que depois vai parar no repositório. O modelo não faz ideia de que o seu exemplo vai para produção. Pior: depois do push, um segredo fica no histórico do Git para sempre, mesmo que você o apague do arquivo atual, e a única correção real é rotacionar a chave.
  • Injection: SQL e comandos. Queries montadas por concatenação de strings em vez de parametrização. "SELECT * FROM users WHERE id = " + userId é um clássico que o modelo continua sugerindo, porque o viu milhões de vezes nos dados de treinamento.
  • XSS no frontend. Renderizar dados do usuário sem escaping, dangerouslySetInnerHTML com input não confiável, falta de um Content-Security-Policy.
  • Dependências inseguras. O modelo sugere um pacote que existe, mas está abandonado, tem uma vulnerabilidade conhecida ou, no pior caso, nem existe, e alguém mal-intencionado registrou esse nome no npm (typosquatting e “slopsquatting”).
  • Permissões amplas demais. Um bucket S3 configurado como público, uma role IAM com *:*, CORS aberto para *, uma porta de banco de dados exposta para o mundo. “Para funcionar”, e funciona mesmo, para todo mundo.
  • Autenticação fraca. JWTs sem verificação de assinatura, senhas com hash MD5, nenhum rate limiting no endpoint de login, sessões que nunca expiram.

Nenhuma delas é uma vulnerabilidade nova. Todas estão no OWASP Top 10 há anos. O que é novo é a velocidade com que chegam à produção.

Por que a IA piora alguns riscos

Dois mecanismos transformam o assistente em um multiplicador de risco, e não na fonte do risco em si.

Velocidade. Quando você escreve à mão, tem um filtro natural de tempo: cada linha custa segundos de reflexão. Com um agente, você recebe 200 linhas em dez segundos. O volume de código que “passa voando” pela sua atenção sem uma revisão de verdade cresce uma ordem de grandeza. A brecha no seu processo de revisão não é constante: ela cresce na mesma proporção da velocidade com que você gera código.

Confiança. Este é o mais perigoso. O código do modelo é sintaticamente perfeito: nomes de variáveis sensatos, comentários, tratamento de erros, todos os parênteses fechados. Parece código de sênior. Nosso cérebro lê essa estética como sinal de competência e baixa a guarda. Enquanto isso, um try/catch caprichado pode capturar um erro e engoli-lo em silêncio, e uma função com um nome bonito como sanitizeInput pode não sanitizar nada. Plausibilidade não é correção.

Some-se a isso a alucinação: um modelo inventa com toda a confiança uma flag de configuração, um método de SDK ou um pacote que não existe. Em um contexto de segurança, isso significa que “ativei a criptografia” pode ser a chamada de uma opção inexistente que, em silêncio, não faz nada.

Um checklist antes do deploy

Antes que o código gerado vá para produção, passe por estes pontos. Você não precisa fazer tudo à mão (a maior parte pode ser automatizada), mas nenhum ponto pode ser pulado “porque é só um MVP”.

  1. Segredos. O diff está livre de qualquer chave, senha ou token? Tudo o que é sensível está em variáveis de ambiente, com o .env no .gitignore?
  2. Input do usuário. Todo dado externo (request, formulário, parâmetro de URL, arquivo) é validado e parametrizado? Queries ao banco de dados: nunca por concatenação.
  3. Permissões. Roles, buckets e CORS estão restritos ao mínimo? Privilégio mínimo: tudo fechado por padrão, e você abre só o que é necessário.
  4. Dependências. Cada pacote novo realmente existe, é mantido e está livre de CVEs conhecidas? Confira o número de downloads e a data da última publicação antes de adicioná-lo ao package.json.
  5. Autenticação e autorização. Os endpoints protegidos realmente verificam a identidade e as permissões? A falta de controle de acesso no nível do objeto é a falha mais comum em APIs.
  6. Tratamento de erros. Algum catch engole um erro em silêncio? As mensagens de erro evitam vazar stack traces ou dados sensíveis para o usuário?
  7. Entendimento. Você consegue explicar o que cada linha não óbvia faz? Se você não entende um trecho, ele não vai para produção. Pedir ao modelo que explique não custa nada.

Ferramentas que fazem esse trabalho por você

Um checklist de cabeça não escala. Felizmente, a maioria dessas classes é detectada por automação, e ela deveria ser um gate no CI, não uma opção.

Varredura de segredos. Gitleaks ou TruffleHog como hook de pre-commit e como etapa do pipeline. Ative também a push protection no nível do repositório (GitHub e GitLab já trazem isso embutido). É a primeira e mais barata linha de defesa: um segredo que nunca chega ao histórico não precisa ser rotacionado.

SAST, ou análise estática. Semgrep, CodeQL ou Snyk Code leem o código sem executá-lo e sinalizam padrões de injection, XSS ou APIs inseguras. O Semgrep tem uma sintaxe de regras legível, e é fácil escrever regras próprias sob medida para a sua stack.

Auditoria de dependências. npm audit, Dependabot ou Snyk: eles verificam vulnerabilidades conhecidas na árvore de dependências e abrem PRs de atualização. Coloque isso no CI com um limite: high e critical bloqueiam o merge.

Varredura de infraestrutura. Se você tem manifestos de Terraform ou Kubernetes, Checkov ou tfsec vão pegar um bucket público e uma role IAM ampla demais antes que qualquer coisa seja provisionada. Isso importa especialmente no vibecoding, porque os modelos geram de bom grado configurações “escancaradas” só para a coisa passar, e defaults seguros já exigem uma decisão humana consciente.

Importante: essas ferramentas também geram falsos positivos. O papel delas não é substituir o raciocínio, apenas reduzir a superfície que um humano precisa revisar. Um pipeline verde não é um certificado de segurança: é a ausência de problemas conhecidos.

A mentalidade certa: a IA é um júnior rápido, não um auditor

O modelo mental mais saudável que conheço: trate o assistente como um estagiário muito capaz e muito rápido. Ele escreve uma quantidade impressionante de código, conhece a sintaxe melhor do que você e nunca se cansa. E, como todo júnior, não tem contexto sobre o seu sistema, não arca com as consequências de um incidente e às vezes afirma coisas falsas com total confiança.

Há duas coisas que você não faz com um júnior: não coloca o código dele em produção sem revisão e não o transforma em revisor do próprio trabalho. As mesmas duas regras valem para o modelo. Você pode pedir à IA que aponte possíveis problemas de segurança (isso ajuda como um par extra de olhos), mas não dispensa uma verificação de verdade. Um revisor que escreveu o código tem um ponto cego exatamente onde errou.

A responsabilidade pela segurança fica com o humano que aperta “deploy”. A questão não é desconfiar da ferramenta, e sim saber quem atende o telefone às três da manhã.

TL;DR

Código de IA não é intrinsecamente seguro nem inseguro: ele é não verificado. Os riscos reais são os velhos conhecidos: segredos no código, injection, XSS, dependências inseguras, permissões amplas demais e fé cega em código bonito. A IA os agrava pela velocidade e pela falsa confiança. A defesa é um checklist antes do deploy mais automação no CI: varredura de segredos, SAST, auditoria de dependências e varredura de infraestrutura. A mentalidade que funciona: a IA é um júnior rápido, não um auditor de segurança, e a revisão e a responsabilidade continuam com você.

Código gerado por IA é seguro? Vibecoding e segurança | vibecoding.inc