
Preuve de concept démontrant le contournement d'autorisation dans RegexRequestMatcher de Spring Security (CVE-2022-22978) via une injection CRLF, avec analyse et étapes d'atténuation.
Selon les informations que j'ai recueillies, il s'agit d'une vulnérabilité liée à la classe RegexRequestMatcher du framework Spring Security. Plus précisément, les applications utilisant RegexRequestMatcher avec une expression régulière contenant un point (.) peuvent être contournées en utilisant les caractères \r(%0a) , \n(%0d) ; ainsi, les attaquants peuvent accéder sans authentification à des chemins non autorisés.
Versions du framework Spring Security concernées par la vulnérabilité :
5.5.x avant 5.5.75.6.x avant 5.6.4Nous devons accéder au code source de Spring Security pour analyser statiquement cette vulnérabilité. Plus précisément, j'utilise la fonction de comparaison des commits entre les versions 5.6.3 (version vulnérable) et 5.6.4 (version corrigée) sur Github. Voir le lien suivant : Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

J'examine les modifications apportées à la classe RegexRequestMatcher. On peut voir que dans la version 5.6.4, cette classe utilise Pattern.DOTALL au lieu du . par défaut de la version 5.6.3.
Où :
Pattern : l'une des trois classes du paquet java.util.regex, qui traite les expressions régulières.Pattern.DOTALL : Lorsque ce flag est utilisé, le "." dans l'expression régulière correspond à tous les caractères, y compris les sauts de ligne comme \n , \r.Pattern.CASE_INSENSITIVE : ignore la casse.
Par défaut, le point . dans une expression régulière correspond à tous les caractères sauf les sauts de ligne comme \n, \r. Ainsi, si une fonction regex valide le motif d'une chaîne, cette fonction ne correspondra pas si la chaîne contient des sauts de ligne. Pour éviter cela, on peut utiliser le flag Pattern.DOTALL.
Cependant, si quelqu'un utilise intentionnellement %0d au lieu de \n ou %0a au lieu de \r, la regex ci-dessus ne correspond toujours pas. Par conséquent, dans la version 5.6.4, un contrôle supplémentaire a été ajouté dans RegexRequestMatcherTests.java. Plus précisément, il convertit %0d et %0a respectivement en \n et \r avant de vérifier avec la regex.

Étape 1: Créer une application web Spring Boot avec Spring Initializr avec les deux dépendances Spring Security et Spring Web.

Étape 2: Créer un Controller qui affiche le texte This is a CVE-2022-22978 demo lorsqu'une requête est faite sur le chemin /admin/*

Étape 3: Mettre en place un mécanisme d'authentification chaque fois qu'un utilisateur accède au chemin /admin/<quelconque> en utilisant regexMatchers("/admin/.*").authenticated(). C'est précisément la vulnérabilité que les attaquants exploitent pour voir le contenu des pages /admin/<quelconque> sans authentification.

Étape 4: Dans le fichier de configuration, déclarez la version de Spring Security qui contient la vulnérabilité. Ici, nous choisissons la version 5.6.3.

Étape 5: Exécutez l'application avec la commande gradlew bootRun, le programme utilise Apache Tomcat par défaut écoutant sur le port 8080. Accédez au chemin /admin/xyz (n'importe quel chemin à partir de /admin/).

Le résultat retourne le code 403 Forbidden, ce qui signifie que nous ne pouvons pas accéder car non authentifié.
À ce stade, en exploitant la vulnérabilité de la fonction regexMatchers dans Spring Security (version 5.6.3) qui ne correspond pas aux caractères de saut de ligne comme \r(%0d) et \n(%0a), nous pouvons accéder au chemin ci-dessus sans authentification avec la payload /admin/%0dxyz

De même avec la payload /admin/%0axyz

Ainsi, nous avons exploité avec succès la vulnérabilité CVE-2022-22978 avec une payload très simple.
5.7.1
Essayez d'attaquer le web avec la même payload : /admin/%0dxyz

Désormais, l'application ne renvoie pas la réponse attendue par l'attaquant.
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1