
Prova de conceito para CVE-2022-22978, demonstrando bypass de autorização no RegexRequestMatcher do Spring Security via injeção CRLF, com uma aplicação de demonstração e análise de correção.
De acordo com as informações que pesquisei, esta é uma vulnerabilidade relacionada à classe RegexRequestMatcher no framework Spring Security. Especificamente, aplicações que usam RegexRequestMatcher cuja expressão regular contém um ponto final (.) 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 analisar esta vulnerabilidade estaticamente. Especificamente, usei o recurso de comparação de commits entre as versões 5.6.3 (versão vulnerável) e 5.6.4 (versão corrigida) do Github. Veja no link: Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

Verifiquei as alterações na classe RegexRequestMatcher. Pode-se ver que na versão 5.6.4, esta classe usa Pattern.DOTALL em vez do . padrão usado na versão 5.6.3.
Onde:
Pattern : é uma das três classes do pacote java.util.regex, responsável por processar expressões regulares.Pattern.DOTALL : Ao usar esta flag, 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 . em uma 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 intencionalmente usar %0d em vez de \n ou %0a em vez de \r, a regex ainda não corresponderá. Portanto, na versão 5.6.4, foi adicionada uma verificação para este caso em RegexRequestMatcherTests.java. Especificamente, ele converte %0d e %0a em \n e \r, respectivamente, antes de verificar com a regex.

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

Passo 2: Criar um Controller que imprime a mensagem This is a CVE-2022-22978 demo quando uma requisição chega ao caminho /admin/*

Passo 3: Configurar 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, declarar a versão do Spring Security que contém a vulnerabilidade. Aqui escolhi a versão 5.6.3.

Passo 5: Executar a aplicação com o comando gradlew bootRun. O programa usa Apache Tomcat por padrão na porta 8080. Acessar o caminho /admin/xyz (qualquer caminho a partir de /admin/).

O resultado retorna o código 403 Forbidden, significando que não é possível acessar devido à falta de autenticação.
Agora, 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) → pode-se 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 com um payload muito simples.
5.7.1
Tentar atacar a web com o mesmo payload: /admin/%0dxyz

Agora, o aplicativo não retorna a resposta esperada 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