Aprimorando os testes de segurança de projetos Go com DepGraphs
Antonio Gomes
26 de agosto de 2020
0 minutos de leituraTemos o prazer de anunciar uma grande melhoria no desempenho dos testes de segurança de projetos Go pela Snyk CLI. Em alguns casos, o tempo de análise caiu mais de 90%! Essa melhoria — que em breve será implementada em outras linguagens — foi possível graças a mudanças no nosso método de análise, que permitem à Snyk lidar com projetos enormes, até mesmo do tamanho do Kubernetes! (falaremos mais sobre isso abaixo).
Dependências, dependências e mais dependências
Aplicações e projetos têm diferentes formatos e tamanhos, mas todos têm algo em comum: incluem dependências de código aberto. Como integrante da equipe de Linguagens da Snyk, também posso afirmar com segurança que projetos que começam pequenos e têm poucas dependências crescem rapidamente e se tornam projetos maiores, com dezenas ou até centenas de dependências diretas e transitivas.
O número de dependências em um projeto pode afetar diretamente o desempenho da análise. Quando alguns usuários reclamaram da lentidão ao analisar ou monitorar seus projetos Go, começamos a buscar uma solução duradoura, capaz de acompanhar o crescimento dos usuários e de seus projetos. A solução escolhida foi migrar a estrutura de dados da nossa aplicação de dependedencyTrees para dependencyGraphs.
DepTrees vs. DepGraphs: aprimorando os testes de segurança
Ao analisar o arquivo de manifesto de um projeto, é criada uma dependencyTree que lista todas as dependências de código aberto usadas por ele, diretas e transitivas. Embora funcione bem para projetos pequenos, esse método se mostrou problemático em projetos maiores. As dependencyTrees ficavam grandes demais e consumiam muita memória.
Para ilustrar e dar uma perspectiva, vamos ver um exemplo básico de como usar uma dependencyTree para lidar com um projeto Go pequeno.

Exemplo básico de uso de uma árvore de dependências para lidar com um projeto Go
As dependências resolvidas desse pequeno projeto Go, usando dependencyTree, ficam assim:

Mesmo com apenas três dependências diretas de código aberto, as dependências transitivas incluídas resultam em uma dependencyTree de 11 MB. Imagine um projeto com mais de 100 dependências diretas. A dependencyTree resultante seria enorme e provavelmente deixaria as análises mais lentas ou até causaria uma falha na análise pela CLI com um erro OutOfMemory.
O modelo de dados fornecido por dependencyGraph resolve esse problema. Com o uso de vértices e arestas, não precisamos mais incluir a mesma dependência várias vezes. Isso reduz bastante o consumo de memória, como mostra a imagem abaixo:

Para o mesmo projeto básico que vimos antes, agora temos um dependencyGraph de 51 KB. Uma grande redução em relação aos 11 MB!
Mais desempenho para... a análise de segurança do Kubernetes
A migração de dependencyTree para dependencyGraph trouxe resultados expressivos e eliminou a lentidão que os projetos Go apresentavam.
Uma história de sucesso interessante foi a de um projeto que alguns leitores talvez já conheçam: o Kubernetes.
Tivemos algumas dificuldades ao tentar analisar o projeto Kubernetes em busca de vulnerabilidades com a Snyk. Isso era resultado direto do modelo de dados anterior, dependencyTree, e do tamanho enorme do projeto.
O novo dependencyGraph ajudou a resolver esses problemas. Agora, testar o repositório principal do Kubernetes pela Snyk CLI é rápido e gera um arquivo de 1,1 MB — um tamanho totalmente aceitável para um projeto tão grande e com tantas camadas.

O que vem por aí?
Sabemos que o desempenho em grande escala é uma preocupação importante para nossos usuários e estamos comprometidos em aprimorar continuamente o suporte a linguagens e ecossistemas. A migração para dependencyGraph é um exemplo disso, e o retorno dos usuários após essa mudança tem sido extremamente positivo.
Como mencionamos, essas mudanças foram aplicadas recentemente à Snyk CLI para projetos Go. Quem usa Java ficará contente em saber que também migramos para dependencyGraph em projetos Java Gradle. Mais uma vez, somente na CLI.
A notícia ainda melhor é que planejamos acelerar a migração para a nova estrutura de dados. Primeiro, em outras linguagens pela CLI (npm, yarn, maven, sbt) e, depois, também fora da CLI, nas nossas integrações com Git.
Em breve teremos mais novidades. Fique de olho e, mais importante ainda, continue protegido!
Comece a resolver desafios de capture the flag
Aprenda a resolver desafios de capture the flag assistindo sob demanda ao nosso workshop virtual introdutório.