Skip to content

Commit 1c6febc

Browse files
committed
Make UriComponentsBuilder.fromOriginHeader() IPv6 compliant
Issue: SPR-13525
1 parent b7c2881 commit 1c6febc

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -338,31 +338,28 @@ public static UriComponentsBuilder fromHttpRequest(HttpRequest request) {
338338

339339

340340
/**
341-
* Create an instance by parsing the "origin" header of an HTTP request.
341+
* Create an instance by parsing the "Origin" header of an HTTP request.
342342
* @see <a href="https://tools.ietf.org/html/rfc6454">RFC 6454</a>
343343
*/
344344
public static UriComponentsBuilder fromOriginHeader(String origin) {
345-
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
346-
if (StringUtils.hasText(origin)) {
347-
int schemaIdx = origin.indexOf("://");
348-
String schema = (schemaIdx != -1 ? origin.substring(0, schemaIdx) : "http");
349-
builder.scheme(schema);
350-
String hostString = (schemaIdx != -1 ? origin.substring(schemaIdx + 3) : origin);
351-
// Handling of invalid origins as described in SPR-13478
352-
int firstSlashIdx = hostString.indexOf("/");
353-
if (firstSlashIdx != -1) {
354-
hostString = hostString.substring(0, firstSlashIdx);
355-
}
356-
if (hostString.contains(":")) {
357-
String[] hostAndPort = StringUtils.split(hostString, ":");
358-
builder.host(hostAndPort[0]);
359-
builder.port(Integer.parseInt(hostAndPort[1]));
345+
Matcher matcher = URI_PATTERN.matcher(origin);
346+
if (matcher.matches()) {
347+
UriComponentsBuilder builder = new UriComponentsBuilder();
348+
String scheme = matcher.group(2);
349+
String host = matcher.group(6);
350+
String port = matcher.group(8);
351+
if (StringUtils.hasLength(scheme)) {
352+
builder.scheme(scheme);
360353
}
361-
else {
362-
builder.host(hostString);
354+
builder.host(host);
355+
if (StringUtils.hasLength(port)) {
356+
builder.port(port);
363357
}
358+
return builder;
359+
}
360+
else {
361+
throw new IllegalArgumentException("[" + origin + "] is not a valid \"Origin\" header value");
364362
}
365-
return builder;
366363
}
367364

368365

spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,14 @@ public void isSameOrigin() {
142142
assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com:80/"));
143143
assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com/path"));
144144
assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com:80/path"));
145+
146+
// Handling of IPv6 hosts as described in SPR-13525
147+
assertTrue(checkSameOrigin("[::1]", -1, "http://[::1]"));
148+
assertTrue(checkSameOrigin("[::1]", 8080, "http://[::1]:8080"));
149+
assertTrue(checkSameOrigin("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]", -1, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]"));
150+
assertTrue(checkSameOrigin("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]", 8080, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8080"));
151+
assertFalse(checkSameOrigin("[::1]", -1, "http://[::1]:8080"));
152+
assertFalse(checkSameOrigin("[::1]", 8080, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8080"));
145153
}
146154

147155

0 commit comments

Comments
 (0)