Como resolver problemas de segurança em uma aplicação Spring MVC
15 de março de 2021
0 minutos de leituraO framework Spring MVC é uma conhecida estrutura Java para criar aplicações web interativas. Ele implementa o padrão arquitetural Model-View-Controller para separar os diferentes aspectos da aplicação. Separar elementos lógicos distintos, como a lógica de apresentação, de entrada e de negócios, geralmente é considerado uma boa prática de arquitetura. Quando implementada corretamente, essa separação de responsabilidades oferece, por exemplo, menos duplicação de código e várias visualizações para o mesmo modelo.
O Spring MVC faz parte do framework Spring e é voltado à criação de aplicações web em Java. Elas podem ser aplicações independentes, usando um servidor web separado, como o Tomcat, ou aplicações Spring Boot.
Para este artigo, criei uma aplicação Spring MVC com páginas web JSP (JavaServer Pages) executada em um servidor Tomcat. O código que escrevi é bem básico e direto. Embora funcione perfeitamente, cometi alguns erros relacionados à segurança. Vamos ver como detectar esses erros na minha aplicação Spring MVC usando análise estática de código Java e como corrigi-los.
Minha aplicação Java Spring MVC
A aplicação Java Spring MVC que criei é bem simples. Ela é baseada em Java 11 e usa uma versão recente do spring-web-mvc. A implementação segue o padrão model-view-controller e interage com o usuário por meio de páginas JSP simples. Você encontra essa aplicação de exemplo no GitHub e pode executá-la com mvn tomcat7:run.
Os recursos básicos da aplicação são:
Enviar um arquivo para uma pasta
Enviar e descompactar um arquivo
Listar os arquivos enviados
Escrever uma mensagem no mural
Listar todas as mensagens
Pesquisar uma mensagem específica.
Limitei as dependências ao mínimo necessário. Embora pudesse usar bibliotecas conhecidas para cuidar das tarefas mais complexas, escrevi toda a lógica de negócios por conta própria. Além de spring-web-mvc, uso:
commons-fileuploadpara enviar os arquivosjstlpara a lógica nos meus arquivos JSPh2, um banco de dados em memória para as mensagens.
Sei que esta aplicação tem alguns erros de segurança no código. Vamos experimentar o recém-lançado Snyk Code e ver como a análise estática de código Java se sai ao encontrar as vulnerabilidades que introduzi.
Snyk Code: ferramenta de análise estática de código Java
O Snyk Code é um novo produto da Snyk, voltado à identificação de construções de código vulneráveis em várias linguagens, incluindo Java. A análise de código Java do Snyk Code também oferece suporte aos principais frameworks, como o Spring MVC que estou usando. Snyk Code é uma ferramenta de teste estático de segurança de aplicações (SAST). Embora SAST seja um termo usado principalmente no universo de segurança da informação, a ferramenta faz exatamente o que o nome indica. Ela analisa seu código Java estaticamente em busca de possíveis vulnerabilidades de segurança. O Snyk Code usa aprendizado de máquina para ajudar você a encontrar vulnerabilidades no código com rapidez e de forma prática para quem desenvolve. Nesta publicação, vamos usar a integração do GitHub com a Snyk para aproveitar o Snyk Code.
Observação: no momento, estou usando uma versão de acesso antecipado do Snyk Code. A disponibilidade geral deve acontecer em abril.
Analisando minha aplicação Java Spring MVC com o Snyk Code
Ativei o Snyk Code nas configurações da minha conta Snyk. Depois da ativação, todos os repositórios que você importar serão analisados pelo Snyk Code. Isso também significa que autorizo a Snyk a inspecionar meu código. Isso não é necessário quando usamos apenas o Snyk Open Source para procurar dependências vulneráveis. Nesse caso, basta ler o arquivo de manifesto, como pom.xml ou build.gradle.

Depois de importar do GitHub o repositório com minha aplicação Java Spring MVC, quase imediatamente vejo que o Snyk Code funcionou: a análise de código Java encontrou problemas de segurança.
A ferramenta encontrou alguns problemas de travessia de diretório relacionados à lógica de envio de arquivos. O Snyk Code também detectou várias vulnerabilidades de injeção de SQL, alguns problemas com cookies e credenciais codificadas diretamente no código. Vamos ver rapidamente alguns deles.
Vulnerabilidade de travessia de diretório no envio de arquivos
Ao enviar um arquivo para minha aplicação Spring MVC, o Snyk Code identificou que não faço nenhuma sanitização do arquivo recebido. Ao gravá-lo no sistema de arquivos sem verificar seu conteúdo, permito uma travessia de diretório. Se um invasor criar uma solicitação POST cujo nome de arquivo seja interpretado como ../../../../../dir/file.x, ele poderá sair do diretório inicial e gravar o arquivo fora da aplicação. Isso também significa que um invasor pode sobrescrever um arquivo existente.

Vulnerabilidade Zip Slip de travessia de diretório
Um problema semelhante de travessia de diretório aparece ao enviar e descompactar arquivos ZIP na minha aplicação Spring MVC. Crio arquivos no sistema de arquivos usando os nomes contidos no arquivo ZIP, sem sanitizá-los. Se o arquivo ZIP tiver o formato mostrado abaixo, você poderá criar ou sobrescrever arquivos fora do escopo da aplicação.
Esse tipo específico de travessia de diretório em um arquivo ZIP é chamado de vulnerabilidade zip-slip. No passado, muitas bibliotecas para compactar e descompactar arquivos ZIP continham essa vulnerabilidade de segurança. Por isso, lembre-se de analisar suas dependências com o Snyk Open Source para detectar bibliotecas vulneráveis.

Vulnerabilidade de injeção de SQL na pesquisa de mensagens
No repositório de mensagens que escrevi para esta aplicação Java Spring MVC, monto manualmente a consulta de pesquisa usando o parâmetro recebido. Como você pode ver na captura de tela abaixo, não uso parametrização de consultas. Com ela, os parâmetros ficam separados da string da consulta. Você pode validar e sanitizar os parâmetros vinculando-os, por exemplo, a um tipo específico. No momento, apenas concateno o parâmetro à consulta existente e a executo. Isso significa que posso manipular a consulta SQL.
Experimente usar o seguinte parâmetro de pesquisa: '; UPDATE message SET text = 'EVIL. Assim, saio da consulta original e executo uma nova instrução que atualiza todas as mensagens. Provavelmente não é isso que você quer — e, felizmente, o Snyk Code nos ajudou a encontrar a vulnerabilidade.

Outras vulnerabilidades encontradas pela análise de código Java
A Snyk também encontrou outros problemas que podem representar riscos. Por exemplo, as propriedades de conexão do meu banco de dados, incluindo nome de usuário e senha, estão codificadas diretamente no repositório. O Snyk Code me alertou para não fazer isso — e com razão.

O Snyk Code também encontrou um problema com um cookie que configurei. Como esta é uma aplicação web Spring MVC, uso um cookie de conveniência no sistema do cliente para armazenar o userID. No entanto, defini a validade máxima desse cookie como um ano. Se você armazenar informações confidenciais em um cookie, não é recomendável definir um valor alto para maxAge. Quando os cookies são usados para armazenar dados temporariamente, eles devem ter um prazo de validade limitado. O Snyk Code me alerta sobre isso por um bom motivo.

Conclusão
Ao criar uma aplicação web simples em Java com Spring MVC, muita coisa pode dar errado. Vale observar que não falei sobre todos os problemas encontrados pelo Snyk Code nesta aplicação de demonstração. Deixo isso como exercício para você.
Se você implementar toda a lógica de negócios por conta própria, problemas de segurança podem passar despercebidos. Saiba que existem bibliotecas bem mantidas que ajudam a alcançar o mesmo objetivo. Um ótimo exemplo no framework Spring são as bibliotecas spring-data, que ajudam a consultar seu banco de dados. Ao usar bibliotecas externas, lembre-se de analisá-las com o Snyk Open Source para evitar incluir uma biblioteca vulnerável. Ainda assim, é fácil introduzir problemas de segurança no seu próprio código Java — isso pode acontecer com qualquer pessoa. É difícil identificar essas vulnerabilidades durante uma revisão de código. Felizmente, contamos com uma excelente ferramenta de análise estática de código Java, o Snyk Code, que ajuda você nessa tarefa.
Proteja seu código com inteligência de ponta
Conheça toda a gama de recursos de análise estática (SAST) do Snyk Code em apenas 30 minutos.
