
Prova de Conceito da vulnerabilidade CVE-2022-22978 no framework Spring Security
De acordo com as informações que pesquisei, esta é uma vulnerabilidade relacionada à classe RegexRequestMatcher no framework Spring Security. Especificamente, aplicações que usam RegexRequestMatcher onde a expressão regular contém um ponto (.) podem ser contornadas usando os caracteres \r(%0a) , \n(%0d); assim, atacantes não autenticados podem acessar caminhos não permitidos.
Versões afetadas do framework Spring Security:
5.5.x antes de 5.5.75.6.x antes de 5.6.4Precisamos acessar o código-fonte do Spring Security para fazer uma análise estática dessa vulnerabilidade. Especificamente, usei a funcionalidade de comparação de commits entre as versões 5.6.3 (versão vulnerável) e 5.6.4 (versão corrigida) no Github. Veja no link a seguir: Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

Realizei a verificação das mudanças na classe RegexRequestMatcher. É possível ver que na versão 5.6.4, essa classe usa Pattern.DOTALL em vez do . padrão da versão 5.6.3.
Onde:
Pattern : é uma das três classes no pacote java.util.regex, que lida com expressões regulares.Pattern.DOTALL : Quando esta flag é usada, o “.” na expressão regular corresponde a todos os caracteres, incluindo caracteres de nova linha como \n , \r.Pattern.CASE_INSENSITIVE: ignora maiúsculas e minúsculas.
Por padrão, o ponto . na expressão regular corresponde a todos os caracteres exceto caracteres de nova linha como \n, \r. Assim, se houver uma função regex validando o padrão de uma string, essa regex não corresponderá se houver caracteres de nova linha na string. Para evitar isso, pode-se usar a flag Pattern.DOTALL.
No entanto, se alguém usar intencionalmente %0d em vez de \n ou %0a em vez de \r, a regex acima ainda não corresponderá. Portanto, na versão 5.6.4, foi adicionada uma verificação extra para esse caso em RegexRequestMatcherTests.java. Especificamente, ele converte %0d e %0a respectivamente em \n e \r antes de verificar com a regex.

Passo 1: Crie uma aplicação web Spring Boot usando Spring Initializr com duas dependências: Spring Security e Spring Web.

Passo 2: Crie um Controller que exiba o texto This is a CVE-2022-22978 demo quando houver uma requisição para o caminho /admin/*

Passo 3: Configure um mecanismo de autenticação sempre que um usuário acessar o caminho /admin/<qualquer> usando regexMatchers("/admin/.*").authenticated(). Esta é a vulnerabilidade que os atacantes exploram para visualizar o conteúdo das páginas /admin/<qualquer> sem autenticação.

Passo 4: No arquivo de configuração, declare a versão do Spring Security que contém a vulnerabilidade. Aqui escolhi a versão 5.6.3.

Passo 5: Execute a aplicação com o comando gradlew bootRun; o programa usa por padrão o Apache Tomcat ouvindo na porta 8080. Acesse o caminho /admin/xyz (qualquer caminho a partir de /admin/ serve).

O resultado retorna o código 403 Forbidden, significando que não é possível acessar porque não está autenticado.
Neste momento, explorando a vulnerabilidade da função regexMatchers no Spring Security (versão 5.6.3) quando ela não corresponde a caracteres de nova linha como \r(%0d) e \n(%0a) → podemos acessar o caminho acima sem autenticação usando o payload /admin/%0dxyz

Similarmente com o payload /admin/%0axyz

Assim, exploramos com sucesso a vulnerabilidade CVE-2022-22978 apenas com um payload muito simples.
5.7.1
Tente atacar a web com o mesmo payload: /admin/%0dxyz

Agora, o aplicativo não retorna a resposta desejada pelo atacante.
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1