
Demonstração passo a passo da bypass de autorização CVE-2022-22978 no RegexRequestMatcher do Spring Security, com configuração de aplicativo vulnerável, execução de payload e verificação 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 (.) podem ser contornadas pelos caracteres \r(%0a) , \n(%0d); assim, atacantes sem autenticação podem acessar caminhos não permitidos.
As versões do framework Spring Security afetadas pela vulnerabilidade:
5.5.x anteriores a 5.5.75.6.x anteriores a 5.6.4Precisamos acessar o código fonte do Spring Security para analisar estaticamente esta vulnerabilidade. Especificamente, utilizei 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) do Github. Veja o link a seguir: Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

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

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

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

Passo 3: Configurar o mecanismo de autenticação para quando o usuário acessa o caminho /admin/<qualquer> usando regexMatchers("/admin/.*").authenticated(). Esta é a vulnerabilidade que atacantes exploram para ver 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 escolhemos a versão 5.6.3.

Passo 5: Executar a aplicação com o comando gradlew bootRun; o programa usa por padrão Apache Tomcat escutando na porta 8080. Acessamos 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 por falta de autenticação.
Agora, explorando a vulnerabilidade da função regexMatchers no Spring Security (versão 5.6.3), que 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 com um payload extremamente simples.
5.7.1
Tentar atacar a web com o mesmo payload: /admin/%0dxyz

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