
PoC of CVE-2022-22978 vulnerability in Spring Security framework
According to the information I have gathered, this vulnerability is related to the RegexRequestMatcher class in the Spring Security framework. Specifically, applications using RegexRequestMatcher where the regular expression contains a dot (.) can be bypassed using the characters \r(%0a) , \n(%0d); thus, attackers can access restricted paths without authentication.
The affected versions of the Spring Security framework:
5.5.x prior to 5.5.75.6.x prior to 5.6.4We need to access the Spring Security source code to statically analyze this vulnerability. Specifically, I used the commit comparison feature between versions 5.6.3 (vulnerable version) and 5.6.4 (fixed version) on Github. See the following link: Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

I examined the changes in the RegexRequestMatcher class. It can be seen that in version 5.6.4, this class uses Pattern.DOTALL instead of the default . as in version 5.6.3.
In which:
Pattern : is one of the three classes in the java.util.regex package, used for processing regular expressions.Pattern.DOTALL : When using this flag, the "." in the regular expression will match all characters, including newline characters like \n, \r.Pattern.CASE_INSENSITIVE: ignores case.
By default, the dot . in regular expressions matches all characters except newline characters like \n, \r. Therefore, if there is a regex validation function for a certain string, that regex will not match if there are newline characters in the string. To avoid this, the Pattern.DOTALL flag can be used.
However, if someone intentionally uses %0d instead of \n or %0a instead of \r, the above regex still cannot match. Therefore, in version 5.6.4, an additional check was added for this case in RegexRequestMatcherTests.java. Specifically, it converts %0d and %0a to \n and \r respectively before checking with regex.

Step 1: Create a Spring Boot web application using Spring Initializr with two dependencies: Spring Security and Spring Web.

Step 2: Create a Controller that prints the text This is a CVE-2022-22978 demo when a request is made to the /admin/* path.

Step 3: Set up an authentication mechanism for users accessing the path /admin/<any> by using regexMatchers("/admin/.*").authenticated(). This is the vulnerability that attackers exploit to view the content of /admin/<any> pages without authentication.

Step 4: In the configuration file, declare the version of Spring Security that contains the vulnerability. I chose version 5.6.3.

Step 5: Run the application with the command gradlew bootRun. By default, the program uses Apache Tomcat listening on port 8080. Access the path /admin/xyz (any path starting with /admin/ works).

The result returns a 403 Forbidden status, meaning access is denied due to lack of authentication.
Now, exploiting the vulnerability of the regexMatchers function in Spring Security (version 5.6.3) which does not match newline characters like \r(%0d) and \n(%0a), we can access the above path without authentication by using the payload /admin/%0dxyz.

Similarly with the payload /admin/%0axyz.

Thus, we have successfully exploited the CVE-2022-22978 vulnerability with just a very simple payload.
5.7.1.
Attempt to attack the web with the same payload as before: /admin/%0dxyz.

At this point, the application no longer returns the response the attacker expected.
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1