CVE-2024-22259: Spring Framework URL Parsing with Host Validation (2nd report)
Description
Applications that use UriComponentsBuilder in Spring Framework to parse an externally provided URL (e.g. through a query parameter) AND perform validation checks on the host of the parsed URL may be vulnerable to a open redirect https://cwe.mitre.org/data/definitions/601.html attack or to a SSRF attack if the URL is used after passing validation checks.
This is the same as CVE-2024-22243 https://spring.io/security/cve-2024-22243 , but with different input.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Spring Framework's UriComponentsBuilder parses URLs in a way that host validation can be bypassed, leading to open redirect or SSRF attacks.
Vulnerability
Description
CVE-2024-22259 is a vulnerability in Spring Framework's UriComponentsBuilder that affects applications which parse an externally provided URL (e.g., through a query parameter) and then perform host validation checks on the parsed host. Due to an overly permissive regular expression used for extracting the host component, a specially crafted URL can cause the host to be parsed differently than expected, allowing an attacker to bypass the application's host validation. This is the same root cause as CVE-2024-22243 but triggered via a different input pattern [1].
Attack
Vector
The vulnerability is exploited by supplying a malicious URL that contains characters like @ or [ in a way that the regex HOST_IPV4_PATTERN or USERINFO_PATTERN no longer correctly identifies the host boundary. The fix involves tightening these regex patterns—for example, changing HOST_IPV4_PATTERN from [^\[/?#:]* to [^/?#:]* and USERINFO_PATTERN from ([^@/?#]*) to ([^/?#]*), as seen in the commit diffs [2][3][4]. An attacker can craft a URI such that the host portion appears valid to the application's validation logic but actually redirects to a different host when the URL is later used.
Impact
A successful exploit can lead to an open redirect (CWE-601) or a server-side request forgery (SSRF) attack, depending on how the parsed URL is used in the application. Open redirect allows an attacker to redirect users to a malicious site, while SSRF enables the attacker to make requests from the application's server to internal or external systems that would otherwise be blocked [1].
Mitigation
Spring Framework has released patches that modify the internal regex used by UriComponentsBuilder to ensure that the host extraction is robust. The fix is included in Spring Framework versions 6.1.5, 6.0.18, 5.3.34, and 5.2.25 (or later releases in the corresponding series). Users should upgrade to the patched versions. No workaround is available, as the vulnerability is in the framework's URL parsing logic [1][2][3][4].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.springframework:spring-webMaven | >= 6.1.0, < 6.1.5 | 6.1.5 |
org.springframework:spring-webMaven | >= 6.0.0, < 6.0.18 | 6.0.18 |
org.springframework:spring-webMaven | < 5.3.33 | 5.3.33 |
Affected products
12- osv-coords11 versionspkg:apk/chainguard/jenkinspkg:apk/chainguard/jenkins-2.440pkg:apk/chainguard/jenkins-compatpkg:apk/chainguard/jenkins-remotingpkg:apk/chainguard/kayenta-2025.4pkg:apk/chainguard/kayenta-2026.0pkg:apk/chainguard/kayenta-fips-2025.4pkg:apk/wolfi/jenkinspkg:apk/wolfi/jenkins-compatpkg:apk/wolfi/jenkins-remotingpkg:maven/org.springframework/spring-web
< 2.450-r0+ 10 more
- (no CPE)range: < 2.450-r0
- (no CPE)range: < 2.440.3-r0
- (no CPE)range: < 2.450-r0
- (no CPE)range: < 2.450-r0
- (no CPE)range: < 2025.4.3-r6
- (no CPE)range: < 2026.0.2-r6
- (no CPE)range: < 2025.4.3-r7
- (no CPE)range: < 2.450-r0
- (no CPE)range: < 2.450-r0
- (no CPE)range: < 2.450-r0
- (no CPE)range: >= 6.1.0, < 6.1.5
- Spring/Spring Frameworkv5Range: 6.1.x
Patches
3381f790329a4Extract reusable checkSchemeAndPort method
1 file changed · +14 −8
spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java+14 −8 modified@@ -76,9 +76,9 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { private static final String HTTP_PATTERN = "(?i)(http|https):"; - private static final String USERINFO_PATTERN = "([^@/?#]*)"; + private static final String USERINFO_PATTERN = "([^/?#]*)"; - private static final String HOST_IPV4_PATTERN = "[^\\[/?#:]*"; + private static final String HOST_IPV4_PATTERN = "[^/?#:]*"; private static final String HOST_IPV6_PATTERN = "\\[[\\p{XDigit}:.]*[%\\p{Alnum}]*]"; @@ -243,9 +243,7 @@ public static UriComponentsBuilder fromUriString(String uri) { builder.schemeSpecificPart(ssp); } else { - if (StringUtils.hasLength(scheme) && scheme.startsWith("http") && !StringUtils.hasLength(host)) { - throw new IllegalArgumentException("[" + uri + "] is not a valid HTTP URL"); - } + checkSchemeAndHost(uri, scheme, host); builder.userInfo(userInfo); builder.host(host); if (StringUtils.hasLength(port)) { @@ -287,9 +285,7 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) { builder.scheme(scheme != null ? scheme.toLowerCase() : null); builder.userInfo(matcher.group(4)); String host = matcher.group(5); - if (StringUtils.hasLength(scheme) && !StringUtils.hasLength(host)) { - throw new IllegalArgumentException("[" + httpUrl + "] is not a valid HTTP URL"); - } + checkSchemeAndHost(httpUrl, scheme, host); builder.host(host); String port = matcher.group(7); if (StringUtils.hasLength(port)) { @@ -308,6 +304,15 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) { } } + private static void checkSchemeAndHost(String uri, @Nullable String scheme, @Nullable String host) { + if (StringUtils.hasLength(scheme) && scheme.startsWith("http") && !StringUtils.hasLength(host)) { + throw new IllegalArgumentException("[" + uri + "] is not a valid HTTP URL"); + } + if (StringUtils.hasLength(host) && host.startsWith("[") && !host.endsWith("]")) { + throw new IllegalArgumentException("Invalid IPV6 host in [" + uri + "]"); + } + } + /** * Create a new {@code UriComponents} object from the URI associated with * the given HttpRequest while also overlaying with values from the headers @@ -363,6 +368,7 @@ public static UriComponentsBuilder fromOriginHeader(String origin) { if (StringUtils.hasLength(port)) { builder.port(port); } + checkSchemeAndHost(origin, scheme, host); return builder; } else {
297cbae2990eExtract reusable checkSchemeAndPort method
1 file changed · +14 −8
spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java+14 −8 modified@@ -77,9 +77,9 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { private static final String HTTP_PATTERN = "(?i)(http|https):"; - private static final String USERINFO_PATTERN = "([^@/?#]*)"; + private static final String USERINFO_PATTERN = "([^/?#]*)"; - private static final String HOST_IPV4_PATTERN = "[^\\[/?#:]*"; + private static final String HOST_IPV4_PATTERN = "[^/?#:]*"; private static final String HOST_IPV6_PATTERN = "\\[[\\p{XDigit}:.]*[%\\p{Alnum}]*]"; @@ -252,9 +252,7 @@ public static UriComponentsBuilder fromUriString(String uri) { builder.schemeSpecificPart(ssp); } else { - if (StringUtils.hasLength(scheme) && scheme.startsWith("http") && !StringUtils.hasLength(host)) { - throw new IllegalArgumentException("[" + uri + "] is not a valid HTTP URL"); - } + checkSchemeAndHost(uri, scheme, host); builder.userInfo(userInfo); builder.host(host); if (StringUtils.hasLength(port)) { @@ -296,9 +294,7 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) { builder.scheme(scheme != null ? scheme.toLowerCase() : null); builder.userInfo(matcher.group(4)); String host = matcher.group(5); - if (StringUtils.hasLength(scheme) && !StringUtils.hasLength(host)) { - throw new IllegalArgumentException("[" + httpUrl + "] is not a valid HTTP URL"); - } + checkSchemeAndHost(httpUrl, scheme, host); builder.host(host); String port = matcher.group(7); if (StringUtils.hasLength(port)) { @@ -317,6 +313,15 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) { } } + private static void checkSchemeAndHost(String uri, @Nullable String scheme, @Nullable String host) { + if (StringUtils.hasLength(scheme) && scheme.startsWith("http") && !StringUtils.hasLength(host)) { + throw new IllegalArgumentException("[" + uri + "] is not a valid HTTP URL"); + } + if (StringUtils.hasLength(host) && host.startsWith("[") && !host.endsWith("]")) { + throw new IllegalArgumentException("Invalid IPV6 host in [" + uri + "]"); + } + } + /** * Create a new {@code UriComponents} object from the URI associated with * the given HttpRequest while also overlaying with values from the headers @@ -402,6 +407,7 @@ public static UriComponentsBuilder fromOriginHeader(String origin) { if (StringUtils.hasLength(port)) { builder.port(port); } + checkSchemeAndHost(origin, scheme, host); return builder; } else {
f2fd2f12269cExtract reusable checkSchemeAndPort method
1 file changed · +14 −8
spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java+14 −8 modified@@ -77,9 +77,9 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { private static final String HTTP_PATTERN = "(?i)(http|https):"; - private static final String USERINFO_PATTERN = "([^@/?#]*)"; + private static final String USERINFO_PATTERN = "([^/?#]*)"; - private static final String HOST_IPV4_PATTERN = "[^\\[/?#:]*"; + private static final String HOST_IPV4_PATTERN = "[^/?#:]*"; private static final String HOST_IPV6_PATTERN = "\\[[\\p{XDigit}:.]*[%\\p{Alnum}]*]"; @@ -252,9 +252,7 @@ public static UriComponentsBuilder fromUriString(String uri) { builder.schemeSpecificPart(ssp); } else { - if (StringUtils.hasLength(scheme) && scheme.startsWith("http") && !StringUtils.hasLength(host)) { - throw new IllegalArgumentException("[" + uri + "] is not a valid HTTP URL"); - } + checkSchemeAndHost(uri, scheme, host); builder.userInfo(userInfo); builder.host(host); if (StringUtils.hasLength(port)) { @@ -296,9 +294,7 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) { builder.scheme(scheme != null ? scheme.toLowerCase() : null); builder.userInfo(matcher.group(4)); String host = matcher.group(5); - if (StringUtils.hasLength(scheme) && !StringUtils.hasLength(host)) { - throw new IllegalArgumentException("[" + httpUrl + "] is not a valid HTTP URL"); - } + checkSchemeAndHost(httpUrl, scheme, host); builder.host(host); String port = matcher.group(7); if (StringUtils.hasLength(port)) { @@ -317,6 +313,15 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) { } } + private static void checkSchemeAndHost(String uri, @Nullable String scheme, @Nullable String host) { + if (StringUtils.hasLength(scheme) && scheme.startsWith("http") && !StringUtils.hasLength(host)) { + throw new IllegalArgumentException("[" + uri + "] is not a valid HTTP URL"); + } + if (StringUtils.hasLength(host) && host.startsWith("[") && !host.endsWith("]")) { + throw new IllegalArgumentException("Invalid IPV6 host in [" + uri + "]"); + } + } + /** * Create a new {@code UriComponents} object from the URI associated with * the given HttpRequest while also overlaying with values from the headers @@ -402,6 +407,7 @@ public static UriComponentsBuilder fromOriginHeader(String origin) { if (StringUtils.hasLength(port)) { builder.port(port); } + checkSchemeAndHost(origin, scheme, host); return builder; } else {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-hgjh-9rj2-g67jghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-22259ghsaADVISORY
- github.com/spring-projects/spring-framework/commit/297cbae2990e1413537c55845a7e0ea0ffd9f9bbghsaWEB
- github.com/spring-projects/spring-framework/commit/381f790329a48b74c2a49fc1384dd68ca9153501ghsaWEB
- github.com/spring-projects/spring-framework/commit/f2fd2f12269c6a781c5b2c20b3c24141055a3d68ghsaWEB
- security.netapp.com/advisory/ntap-20240524-0002ghsaWEB
- spring.io/security/cve-2024-22259ghsaWEB
- security.netapp.com/advisory/ntap-20240524-0002/mitre
News mentions
0No linked articles in our index yet.