Skip to content

Commit e8c656d

Browse files
committed
Reject invalid forwarded headers
Issue: SPR-16660
1 parent bcda243 commit e8c656d

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

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

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -677,36 +677,43 @@ public UriComponentsBuilder fragment(String fragment) {
677677
* @since 4.2.7
678678
*/
679679
UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
680-
String forwardedHeader = headers.getFirst("Forwarded");
681-
if (StringUtils.hasText(forwardedHeader)) {
682-
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
683-
Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
684-
if (matcher.find()) {
685-
scheme(matcher.group(1).trim());
686-
port(null);
687-
}
688-
matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
689-
if (matcher.find()) {
690-
adaptForwardedHost(matcher.group(1).trim());
691-
}
692-
}
693-
else {
694-
String protocolHeader = headers.getFirst("X-Forwarded-Proto");
695-
if (StringUtils.hasText(protocolHeader)) {
696-
scheme(StringUtils.tokenizeToStringArray(protocolHeader, ",")[0]);
697-
port(null);
680+
try {
681+
String forwardedHeader = headers.getFirst("Forwarded");
682+
if (StringUtils.hasText(forwardedHeader)) {
683+
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
684+
Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
685+
if (matcher.find()) {
686+
scheme(matcher.group(1).trim());
687+
port(null);
688+
}
689+
matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
690+
if (matcher.find()) {
691+
adaptForwardedHost(matcher.group(1).trim());
692+
}
698693
}
694+
else {
695+
String protocolHeader = headers.getFirst("X-Forwarded-Proto");
696+
if (StringUtils.hasText(protocolHeader)) {
697+
scheme(StringUtils.tokenizeToStringArray(protocolHeader, ",")[0]);
698+
port(null);
699+
}
699700

700-
String hostHeader = headers.getFirst("X-Forwarded-Host");
701-
if (StringUtils.hasText(hostHeader)) {
702-
adaptForwardedHost(StringUtils.tokenizeToStringArray(hostHeader, ",")[0]);
703-
}
701+
String hostHeader = headers.getFirst("X-Forwarded-Host");
702+
if (StringUtils.hasText(hostHeader)) {
703+
adaptForwardedHost(StringUtils.tokenizeToStringArray(hostHeader, ",")[0]);
704+
}
704705

705-
String portHeader = headers.getFirst("X-Forwarded-Port");
706-
if (StringUtils.hasText(portHeader)) {
707-
port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0]));
706+
String portHeader = headers.getFirst("X-Forwarded-Port");
707+
if (StringUtils.hasText(portHeader)) {
708+
port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0]));
709+
}
708710
}
709711
}
712+
catch (NumberFormatException ex) {
713+
throw new IllegalArgumentException("Failed to parse a port from \"forwarded\"-type headers. " +
714+
"If not behind a trusted proxy, consider using ForwardedHeaderFilter " +
715+
"with the removeOnly=true. Request headers: " + headers);
716+
}
710717

711718
if (this.scheme != null && ((this.scheme.equals("http") && "80".equals(this.port)) ||
712719
(this.scheme.equals("https") && "443".equals(this.port)))) {

0 commit comments

Comments
 (0)