TL;DR
Vulnerability Details
Affected versions of Spring parse the "userinfo" segment of URLs in a unique way, potentially resulting in the extraction of a host name segment that differs from many other common libraries.
The abnormal behavior is due to the following regular expression ("regex") in the UriComponentsBuilder class (introduced by this commit in 2014):
private static final String USERINFO_PATTERN = "([^@\\[/?#]*)";
This regex does not permit the "left bracket" character ([) in the user info segment. However, Spring appears to be an outlier with this behavior, so calling getHost() on a UriComponents object constructed using UriComponentsBuilder.fromUriString or UriComponentsBuilder.fromHttpUrl can result in unexpected behavior. The RestTemplate, RestClient, and WebClient classes are also affected due to their internal use of UriComponentsBuilder; therefore, implementations can be rendered vulnerable even without direct use of UriComponentsBuilder.
For specially-crafted inputs, Spring will return a host name value that differs from all of the following:
-
Modern web browsers, including:
- Chrome (and other Chromium-based browsers)
- Firefox
- Safari
- java.net.URI (reportedly only for specific Java versions; other versions raise a URISyntaxException)
- java.net.URL
- curl
- android.net.Uri
- okhttp3.HttpUrl
- (Python 3) urllib.parse.urlparse
(Note that this list is non-exhaustive.)
This behavior potentially renders Spring-based web applications vulnerable to open redirect and server-side request forgery (SSRF) if the dependent implementation uses trusted host names for authorization or other security-relevant mechanisms.
Example Implementation
I discovered this vulnerability during a routine penetration test of a proprietary implementation. As such, I'm not at liberty to share that code. For this reason, I created an intentionally-vulnerable implementation of a simple Spring-based web application that demonstrates what some vulnerable code paths might look like. It can also be used as a reference implementation if someone wants to use CVE-2024-22243 for a CTF challenge.
The example implementation has two endpoints: one that demonstrates an open redirect, and another that demonstrates SSRF. More details can be found in the project Readme.
Semgrep Rules
The example repository also contains semgrep rules to assist in scanning for potentially-vulnerable code paths. spring-cve-2024-22243_loose.yaml performs naïve scans for any use of the vulnerable APIs; as such, it will often return a large number of false positives. spring-cve-2024-22243_strict.yaml attempts to use stricter logic and taint analysis; however, this has not been thoroughly tested and has high potential to miss some vulnerable implementations (especially when not using Semgrep Pro, which is required for cross-file analysis).
Additional Resources
- CVE-2024-22243 disclosures & details:
- Git commit that introduced the vulnerability
- Git commit that fixed the vulnerability
- Vulnerable implementation demo: Open redirect and SSRF by Sean Pesce
- Vulnerable implementation demo: OAuth flow with open redirect by threedr3am of SecCoder Security Lab
- CVE-2024-22259, a second URL-parsing vulnerability that was discovered in the fallout of CVE-2024-22243
- CVE-2024-22262, a third URL-parsing vulnerability that was discovered in the fallout of the first two findings
- PortSwigger's URL Validation Bypass Cheat Sheet, which now contains my payloads for exploiting this vulnerability (relevant blog post)
No comments:
Post a Comment