Pular para o conteúdo
Categoria: Desenvolvendo com IA13 min de leitura

Segurança do código gerado por IA: cuidados essenciais

Por Schematize Blog ·

Entenda por que sugestões de IA podem trazer vulnerabilidades silenciosas e aprenda a revisar esse código com método antes de levá-lo para produção com segurança.

Assistentes de código como Copilot e Cursor aumentaram a produtividade de muita gente, mas eles não foram treinados para escrever código seguro — foram treinados para escrever código plausível. Essa diferença é a origem de uma classe inteira de bugs que passam despercebidos no commit e só aparecem quando alguém os explora. Neste artigo você vai entender por que isso acontece e o que fazer para revisar com método.

Por que a IA gera código inseguro

Modelos de geração de código aprendem com bilhões de linhas de repositórios públicos. O problema é que boa parte desse material contém más práticas: concatenação de SQL, segredos hardcoded, validação ausente e bibliotecas desatualizadas. O modelo replica esses padrões porque eles são estatisticamente comuns, não porque são corretos.

O estudo clássico de Pearce e colegas (2022) investigou exatamente isso. Os autores submeteram o GitHub Copilot a uma bateria de cenários de programação relevantes para segurança e encontraram que cerca de 40% dos programas gerados continham vulnerabilidades em pelo menos uma das completions sugeridas. A conclusão é direta: a ferramenta é útil, mas não é um revisor de segurança.

Há razões técnicas por trás disso que vale entender:

    Há ainda um efeito psicológico. Quando o código aparece pronto, formatado e com aparência profissional, a tendência é confiar. Esse viés de automação reduz o escrutínio justamente no momento em que ele seria mais necessário. Estudos de fatores humanos mostram que revisamos com menos rigor aquilo que uma máquina produz com aparência de autoridade — e o código de IA é o exemplo perfeito.

    As vulnerabilidades mais comuns em sugestões de IA

    Os padrões inseguros que mais aparecem em código gerado se sobrepõem fortemente às falhas catalogadas no OWASP Top 10 explicado: as 10 maiores falhas de segurança web. Vale conhecer os suspeitos de sempre:

      Exemplo concreto: injeção de SQL

      Veja uma sugestão típica que parece correta, mas é perigosa:

      # INSEGURO — sugestão comum de IA
      def buscar_usuario(email):
          query = f"SELECT * FROM usuarios WHERE email = '{email}'"
          return db.execute(query)

      O input email entra direto na string. Um atacante envia ' OR '1'='1 e a lógica da consulta é subvertida. A versão segura usa parâmetros:

      # SEGURO — consulta parametrizada
      def buscar_usuario(email):
          query = "SELECT * FROM usuarios WHERE email = %s"
          return db.execute(query, (email,))

      A diferença é sutil no diff, mas é a fronteira entre uma aplicação saudável e um vazamento de banco de dados.

      Exemplo concreto: injeção de comando

      Outro padrão recorrente é montar um comando de sistema concatenando entrada do usuário:

      import os
      
      # INSEGURO — input direto no shell
      def converter(nome_arquivo):
          os.system(f"convert {nome_arquivo} saida.png")

      Se nome_arquivo for foto.jpg; rm -rf /, o shell executa os dois comandos. A versão segura evita o shell e passa argumentos como lista, sem interpolação:

      import subprocess
      
      # SEGURO — sem shell, argumentos separados
      def converter(nome_arquivo):
          subprocess.run(["convert", nome_arquivo, "saida.png"], check=True)

      A diferença é não deixar o usuário influenciar a estrutura do comando, apenas os dados. Esse é o princípio comum a toda defesa contra injeção: separar código de dados.

      O risco específico do vibe coding

      O fenômeno do vibe coding: o que é e como construir apps só com prompts amplifica esses riscos. Quando você aceita grandes blocos de código sem ler — confiando apenas na "vibe" de que funciona — você abre mão da única camada de revisão que ainda restava: você mesmo.

      Aplicações construídas inteiramente por prompt costumam acumular dívidas de segurança invisíveis: autenticação implementada pela metade, regras de autorização inexistentes e endpoints internos expostos. O código roda, a demo funciona, e a falha fica dormente até a primeira sondagem maliciosa.

      O perigo se agrava porque vulnerabilidades de autorização e lógica de negócio não quebram nenhum teste funcional. Um endpoint que devolve os dados de qualquer usuário quando você troca o ID na URL funciona perfeitamente do ponto de vista da demo — ele só está "funcionando errado" sob a ótica de um atacante. Como o vibe coding foca em "fazer funcionar", essa classe de falha passa totalmente despercebida.

      A regra prática é simples: quanto menos você lê o código, mais rígido precisa ser o seu pipeline automatizado de verificação. Vibe coding sem testes e sem scanners é uma aposta.

      Prompt injection: quando a entrada vira código

      Há uma categoria de risco que é nova e específica de aplicações com IA. Se o seu app passa input do usuário diretamente para um LLM que toma decisões ou executa ações, você precisa entender prompt injection: a injeção de comandos que ameaça apps de IA. Nesse cenário, o "código" perigoso é o próprio texto do usuário, manipulando o comportamento do modelo.

      Isso significa que revisar o código gerado não basta — é preciso revisar também como o código trata as entradas que chegam ao modelo. As duas frentes se complementam. Um agente de IA com acesso a ferramentas (executar SQL, enviar e-mail, chamar APIs) é especialmente perigoso: uma instrução maliciosa embutida no texto do usuário pode fazer o agente abusar dessas ferramentas. A defesa exige tratar a saída do LLM como não confiável e aplicar autorização fora do modelo, na fronteira de cada ferramenta.

      Como revisar código gerado por IA

      A boa notícia é que técnicas tradicionais de revisão funcionam bem aqui. O segredo é tratar a IA como um desenvolvedor júnior talentoso porém descuidado: aproveite a velocidade, mas confira tudo. As práticas de code review eficiente: como revisar código sem brigar com o time se aplicam integralmente.

      O ponto mental mais importante é o que mudou no equilíbrio do trabalho: com IA, escrever ficou barato e revisar ficou o gargalo. Sua atenção deve migrar de produzir linhas para auditar intenções. Pergunte-se sempre, ao ler um bloco gerado: de onde vêm os dados que isto manipula, e o que acontece se forem maliciosos?

      Checklist de revisão de segurança

        Ferramentas automatizadas que ajudam

        A revisão humana é essencial, mas não escala sozinha. Combine-a com ferramentas:

          O ideal é que esses scanners rodem no CI, falhando o build quando encontram algo crítico. Assim a verificação não depende de alguém lembrar de fazê-la. Um exemplo conceitual de um passo de CI que barra o merge ao detectar problema:

          # trecho ilustrativo de pipeline
          seguranca:
            steps:
              - run: semgrep --config=auto --error      # SAST falha o build em achado
              - run: pip-audit                           # dependências vulneráveis
              - run: gitleaks detect --no-banner         # segredos vazados

          Vale entender o trade-off dessas ferramentas: SAST gera falsos positivos (aponta o que não é problema) e também falsos negativos (deixa passar o que é). Por isso elas complementam, mas não substituem, o olho humano. Ajustar regras para reduzir ruído é parte de manter o pipeline útil — um scanner que grita demais acaba ignorado.

          Dependências: o risco que a IA herda e amplia

          Um vetor que merece destaque próprio é o das dependências. A IA frequentemente sugere instalar bibliotecas para resolver um problema, e aí moram dois perigos distintos. O primeiro é sugerir uma versão com vulnerabilidade conhecida — algo que um scanner de dependências pega. O segundo é mais insidioso: a alucinação de pacotes.

          Modelos às vezes inventam nomes de bibliotecas que não existem, mas que soam plausíveis. Atacantes monitoram esses nomes alucinados recorrentes e publicam pacotes maliciosos com exatamente esses nomes — uma técnica apelidada de slopsquatting. Quem instala cegamente o que a IA sugeriu acaba importando código hostil. A defesa é simples mas exige disciplina: confira que o pacote existe, é mantido e é o oficial antes de instalar. Desconfie especialmente de bibliotecas que você nunca ouviu falar e que aparecem só porque a IA citou.

          # Antes de instalar o que a IA sugeriu, verifique:
          npm view <pacote>          # existe? quem mantém? última publicação?
          npm view <pacote> versions # quais versões? a sugerida é real?

          Esse cuidado se soma ao princípio de tratar toda dependência como superfície de ataque: cada biblioteca importada é código de terceiros rodando com os privilégios da sua aplicação.

          Integrando segurança no fluxo com IA

          A meta não é abandonar os assistentes de código — é usá-los com consciência. Se você está adotando ferramentas como as descritas no GitHub Copilot: guia completo para programar com IA, inclua a segurança no fluxo desde o início.

          Algumas táticas práticas:

            Erros comuns ao confiar na IA

              Perguntas frequentes

              Devo parar de usar Copilot e similares por causa disso? Não. O ganho de produtividade é real e os riscos são gerenciáveis. A resposta certa não é abandonar a ferramenta, e sim emparelhá-la com revisão e automação. Trate-a como um acelerador que exige supervisão, não como um autopilô.

              A IA não consegue revisar a própria segurança? Em parte. Pedir ao modelo para auditar o código que ele mesmo gerou costuma revelar problemas, porque criticar é uma tarefa diferente de criar. Mas isso não substitui SAST, scanners de dependência e revisão humana nos pontos sensíveis — é mais uma camada, não a única.

              Qual a vulnerabilidade mais comum em código de IA? As injeções (SQL, comando) e os segredos hardcoded lideram, justamente porque são padrões abundantes nos dados de treino. Felizmente também são das mais fáceis de pegar com ferramentas automatizadas e com um checklist disciplinado.

              Code review humano ainda vale a pena se eu tenho scanners? Sim, e mais do que nunca. Scanners pegam padrões conhecidos; falhas de lógica de negócio e de autorização — as mais perigosas em apps gerados por IA — exigem entendimento humano do que a aplicação deveria fazer.

              Conclusão

              Código gerado por IA é um acelerador poderoso, mas vem com uma responsabilidade renovada de revisão. O estudo de Pearce e colegas (2022) deixa claro que uma fração relevante das sugestões traz falhas reais, e essas falhas mapeiam diretamente para as categorias do OWASP Top 10 (OWASP Foundation, 2021). A defesa não é desconfiar de tudo nem confiar em tudo — é montar um processo: prompts que pedem segurança e dão contexto de ameaça, revisão humana nos pontos críticos, e ferramentas automatizadas no CI cobrindo o resto. Lembre-se de que o trabalho mudou de lugar: escrever ficou barato, revisar virou o ofício. Trate a IA como um colega rápido que precisa de um bom revisor ao lado, e você ganha a velocidade sem herdar os riscos.

              Referências

                Leituras relacionadas

                Nenhum comentário ainda

                Seja o primeiro a comentar.

                Deixe seu comentário

                Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

                Entrar com Canverly