Skip to main content

Como resolver problemas de segurança em uma aplicação Spring MVC

Escrito por
Blog Header Spring MVC

15 de março de 2021

0 minutos de leitura

O 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-fileupload para enviar os arquivos

  • jstl para a lógica nos meus arquivos JSP

  • h2, 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.

Página de configurações do Snyk com Snyk Code selecionado e ativado por um botão de alternância, além de um botão Salvar alterações

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.

Relatório do Snyk Code sobre path traversal, destacando uma entrada HTTP não sanitizada que chega a Files.write em UploadController.java

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.

-rw-r--r--  18-Apr-15 23:04 good.txt
-rwxrwxrwx  18-Jun-03 17:06 ../../../../../../../../../../../../dir/file.x

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.

Visualização do Snyk Code de uma vulnerabilidade de travessia de caminho, com explicação e fluxo de dados destacado no código Java de UploadController.java

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.

Relatório de injeção de SQL do Snyk mostrando uma entrada HTTP não sanitizada chegando a uma chamada executeQuery em Java e o código vulnerável destacado.

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.

A verificação de segurança sinaliza credenciais de banco de dados codificadas diretamente no código Java, mostrando uma chamada de conexão com DB_URL, USER e PASS.

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.

Achado de segurança relacionado ao tempo de expiração insuficiente da sessão, mostrando um trecho de código do CookieUtil.java de um aplicativo Spring MVC com um cookie configurado para durar um ano.

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.