Copilot amplifica bases de código inseguras replicando vulnerabilidades em projetos
Randall Degges
22 de fevereiro de 2024
0 minutos de leituraVocê sabia que o GitHub Copilot pode sugerir código inseguro quando a base de código existente apresenta problemas de segurança? Por outro lado, se a base de código já é altamente segura, o Copilot é menos propenso a gerar código com problemas de segurança. Os assistentes de codificação baseados em IA podem sugerir código inseguro devido à sua compreensão limitada da base de código específica. Eles imitam padrões aprendidos ou utilizam o contexto disponível sem discernimento. Para melhorar o comportamento do Copilot, você pode fornecer exemplos melhores para seu aprendizado, mas isso não garante a segurança ou proteção contra vulnerabilidades de segurança. Essa situação é semelhante à teoria das "janelas quebradas", a qual estipula que sinais visíveis de crime, comportamento antissocial e desordem civil criam um ambiente urbano que incentiva o aumento desse tipo de problemas.
Neste post, veremos um exemplo real de como o Copilot pode replicar problemas de segurança existentes no código. Nele, o Copilot é adotado em um projeto que tem muitas vulnerabilidades e usa a função de guias vizinhas para acessar código de arquivos abertos no IDE a fim de obter contexto. Como o contexto contém vulnerabilidades, as sugestões do Copilot amplificam os problemas de segurança no projeto. Isso significa que a dívida técnica presente em um projeto pode aumentar ainda mais a insegurança dos desenvolvedores que usam o Copilot. Veremos isso em mais detalhes na próxima seção.
Em contrapartida, o Copilot é menos propenso a sugerir código inseguro em projetos livres de problemas de segurança, pois tem menos contexto de código inseguro disponível para uso. Esse é um grande incentivo para investir tempo na redução de vulnerabilidades da base de código existente, já que isso minimiza a introdução futura de problemas por assistentes de codificação baseados em IA generativa. Segundo dados da Snyk, em um projeto comercial comum, o código desenvolvido internamente tem uma média de 40 vulnerabilidades. Cerca de um terço desses problemas são de alta gravidade. É nesse cenário que as ferramentas de geração de IA podem duplicar código usando essas vulnerabilidades como contexto. Os problemas mais comuns que a Snyk vê em projetos comerciais são script entre sites (XSS), travessia de caminho, segredos e credenciais codificados e injeção de SQL.
Compreensão do problema
Assistentes de codificação baseados em IA generativa, como GitHub Copilot, AWS CodeWhisperer e ChatGPT, representam um avanço significativo na melhoria da produtividade e na eficiência do código. No entanto, lembre-se de que esses assistentes não entendem a semântica do código e, portanto, não podem avaliá-lo. Essencialmente a ferramenta imita o código visto durante o treinamento. A provisão de melhores modelos de função melhora o comportamento, mas não oferece garantias. Se você quer que seu código gerado por IA seja seguro, é preciso instalar uma barricada de segurança.
O contexto é uma parte importante no fornecimento de sugestões relevantes para o usuário.
O Copilot gera trechos de código com base em padrões e estruturas aprendidas em um vasto repositório de código existente. Ele usa "engenharia de prompts" e "guias vizinhas" como contexto para sugerir código relevante. Esses arquivos podem ser guias que você abriu recentemente com arquivos já existentes no projeto. Essa abordagem tem várias vantagens, mas também pode apresentar um ônus crítico no contexto de segurança.
Anteriormente, o Copilot só considerava como contexto o arquivo usado na codificação. Como não podiam usar o resto da base de código, os algoritmos não eram capazes de fazer sugestões relevantes para o projeto como um todo. A próxima etapa foi criar uma biblioteca de prompts, que armazena um grande volume de dados sobre o contexto do desenvolvedor e gera mais informações sobre o prompt do usuário. Dessa forma, os algoritmos conseguem fornecer respostas mais precisas e com maior priorização dos dados contextuais. Por fim, as guias vizinhas são uma técnica que permitem ao Copilot usar os arquivos abertos no IDE do desenvolvedor, priorizando os mais próximos do trabalhado no momento. Quando abrem mais arquivos que são relevantes para o projeto, os desenvolvedores obtém uma correspondência mais forte com os prompts. Akash Sharma, líder da comunidade do GitHub Copilot, descreveu os benefícios dessa funcionalidade em um comentário recente, afirmando que esse comportamento quase dobrou o número de sugestões aceitas do Copilot, de cerca de 20% para 35%.
Mas o que acontece quando os desenvolvedores desse projeto não têm um sólido conhecimento em segurança? E se esses projetos já tiverem problemas de segurança e erros de qualidade, ocasionados por dívida técnica não gerenciada?
De modo resumido, o código sugerido pelo Copilot pode replicar acidentalmente vulnerabilidades de segurança e práticas inadequadas presentes nos arquivos vizinhos. Isso pode resultar em práticas de codificação inseguras e abrir a porta para uma série de vulnerabilidades de segurança.
Vamos ver isso em ação:
No vídeo acima, vemos como é possível pedir ao Copilot que crie algumas consultas SQL para corresponder algumas entradas de usuário com um nome ou descrição de produto no nosso banco de dados. Sabemos como uma vulnerabilidade de injeção de SQL pode afetar um aplicativo e queremos garantir que o código não introduza nenhuma dessas vulnerabilidades. Na primeira solicitação de consulta, recebemos este resultado:
1// create query to match input with the description or product name
2var query = em.createQuery("SELECT p FROM Product p WHERE LOWER(p.description) like OR lower(p.productName) like :input", Product.class);
Parece estar tudo certo com o código, pois usamos parâmetros nomeados que eliminam a vulnerabilidade à injeção de SQL. No entanto, introduzimos um trecho de código vulnerável em uma guia vizinha, que cria uma consulta SQL em outra parte do projeto. Na próxima vez em que enviarmos ao Copilot exatamente a mesma solicitação, ele usará o novo contexto vulnerável e o replicará, propagando essa vulnerabilidade na nova sugestão de código:
1// create query to match input with the description or product name
2String query = "Select * from Product where lower(description) like '%" + lowerInput + "%' OR lower(product_name) like '%" + lowerInput + "%'";
Acabamos de passar de uma injeção de SQL no projeto para duas porque o Copilot usou o código vulnerável como contexto para aprender.
Problemas de segurança agravados
Em bases de código que contêm vulnerabilidades de segurança, esse comportamento pode agravar os problemas de várias formas:
Reforço de maus hábitos: as sugestões de código do Copilot podem reforçar hábitos de codificação inadequados em desenvolvedores inexperientes ou inseguros. Ao notar a replicação de padrões de código inseguros, eles podem presumir que essas práticas são aceitáveis, levando, em última análise, à perpetuação de problemas de segurança.
Falta de revisão: o código gerado pelo Copilot pode ser implementado sem uma revisão completa. Essa ausência de intervenção humana pode resultar na passagem despercebida de vulnerabilidades de segurança, pois nem sempre o contexto de geração do código destaca esses problemas.
Padrões obsoletos e falhos: o Copilot pode sugerir código baseado em padrões de codificação desatualizados ou falhos que anteriormente eram aceitáveis, mas agora são reconhecidos como riscos de segurança.
Questões de segurança ignoradas: o foco do Copilot é a geração de código, e não a avaliação de segurança. Os desenvolvedores podem estar mais preocupados com a funcionalidade do que com a segurança, ignorando involuntariamente as vulnerabilidades.
O que você pode fazer para reduzir o problema?
Para diminuir as chances de os assistentes baseados em IA propagarem problemas de segurança existentes no código, as organizações podem tomar várias medidas:
Os desenvolvedores devem sempre realizar revisões manuais do código gerado por assistentes de codificação. Essas revisões precisam incluir uma avaliação de segurança abrangente para identificar e corrigir vulnerabilidades.
As equipes de segurança devem implementar as proteções do SAST, incluindo políticas estabelecidas a serem seguidas pelas equipes de desenvolvimento. A Snyk pode ajudar a identificar e corrigir rapidamente problemas de segurança em código criado de modo manual ou automático. Você conta com um suporte de correção para ajudar a eliminar os novos problemas adicionados à base de código.
Os desenvolvedores podem aderir a diretrizes de codificação segura definidas pelas equipes de desenvolvimento (defensores da segurança) e equipes de segurança
As equipes de segurança podem fornecer o treinamento e a conscientização necessáriospara as equipes de desenvolvimento, compartilhando uma compreensão das vulnerabilidades de segurança e práticas recomendadas comuns para permitir que os desenvolvedores tomem decisões embasadas quando revisam o código gerado por IA.
As equipes de segurança podem ajudar a priorizar e classificar a lista de problemas pendentes de cada equipe de desenvolvimento. A eliminação dos problemas mais perigosos em cada projeto diminui a probabilidade de sua replicação nas sugestões de código de assistentes de codificação baseados em IA generativa.
As equipes executivas podem exigir proteções de segurança como condição para o uso de assistentes de código baseados em IA generativa, reforçando ainda mais a conscientização sobre os riscos e as mitigações.
Conclusão: os assistentes de codificação baseados em IA precisam de barricadas de segurança
É importante reconhecer que os assistentes de codificação baseados em IA generativa, como o Copilot, não entendem a semântica do código e, portanto, não podem avaliá-lo. Essencialmente a ferramenta imita o código visto durante o treinamento. A provisão de melhores modelos de função melhora o comportamento, mas não oferece garantias. Se você quer que seu código gerado por IA seja seguro, é preciso instalar uma barricada de segurança.
Com isso em mente, é essencial combinar ferramentas de assistente de codificação baseadas em IA generativa com técnicas tradicionais de AppSec para mitigar novos problemas à medida que são introduzidos. Essas técnicas incluem revisões manuais de código, diretrizes de codificação segura, treinamento e testes de análise estática ao longo do SDLC, principalmente nas primeiras etapas em ambientes essenciais, como no IDE onde o código é gerado. Dessa forma, podemos equilibrar inovação e segurança e tornar nossas aplicações mais resilientes a possíveis ameaças.
Além disso, o comportamento de assistentes de codificação baseados em IA generativa aumenta a importância da correção de vulnerabilidades de segurança existentes nas bases de código. Com a redução das vulnerabilidades presentes no código, menos sugestões vulneráveis serão feitas pelos assistentes de codificação baseados em IA.
Comece a proteger o código gerado por IA
Crie sua conta gratuita da Snyk para começar a proteger o código gerado por IA em questão de minutos. Ou agende uma demonstração com um especialista para ver como a Snyk se adapta a seus casos de uso de segurança de desenvolvedores.