Add support for X-Forwarded-For and Forwarded for
See gh-23260, gh-23582
This commit is contained in:
committed by
Rossen Stoyanchev
parent
ff9daa9377
commit
883ad098f9
@@ -55,6 +55,8 @@ public class ForwardedHeaderFilterTests {
|
||||
private static final String X_FORWARDED_PREFIX = "x-forwarded-prefix";
|
||||
|
||||
private static final String X_FORWARDED_SSL = "x-forwarded-ssl";
|
||||
private static final String X_FORWARDED_FOR = "x-forwarded-for";
|
||||
private static final String FORWARDED = "forwarded";
|
||||
|
||||
|
||||
private final ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
|
||||
@@ -74,6 +76,114 @@ public class ForwardedHeaderFilterTests {
|
||||
this.filterChain = new MockFilterChain(new HttpServlet() {});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forwardedForEmpty() throws Exception {
|
||||
this.request.addHeader(X_FORWARDED_FOR, "");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(MockHttpServletRequest.DEFAULT_REMOTE_ADDR);
|
||||
assertThat(actual.getRemoteHost()).isEqualTo(MockHttpServletRequest.DEFAULT_REMOTE_HOST);
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forwardedForSingleIdentifier() throws Exception {
|
||||
this.request.addHeader(X_FORWARDED_FOR, "203.0.113.195");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("203.0.113.195");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forwardedForMultipleIdentifiers() throws Exception {
|
||||
this.request.addHeader(X_FORWARDED_FOR, "203.0.113.195, 70.41.3.18, 150.172.238.178");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("203.0.113.195");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForIpV4Identifier() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=203.0.113.195");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("203.0.113.195");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForIpV6Identifier() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=\"[2001:db8:cafe::17]\"");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("2001:db8:cafe::17");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForUnknownIdentifier() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=unknown");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("unknown");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForObfuscatedIdentifier() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=_abc-12_d.e");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("_abc-12_d.e");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForIpV4IdentifierWithPort() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=\"203.0.113.195:47011\"");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("203.0.113.195");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(47011);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForIpV6IdentifierWithPort() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "For=\"[2001:db8:cafe::17]:47011\"");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("2001:db8:cafe::17");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(47011);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForUnknownIdentifierWithPort() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=\"unknown:47011\"");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("unknown");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(47011);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForObfuscatedIdentifierWithPort() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=\"_abc-12_d.e:47011\"");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("_abc-12_d.e");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(47011);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void standardizedForwardedForMultipleIdentifiers() throws Exception {
|
||||
this.request.addHeader(FORWARDED, "for=203.0.113.195;proto=http, for=\"[2001:db8:cafe::17]\", for=unknown");
|
||||
HttpServletRequest actual = filterAndGetWrappedRequest();
|
||||
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("203.0.113.195");
|
||||
assertThat(actual.getRemotePort()).isEqualTo(MockHttpServletRequest.DEFAULT_SERVER_PORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextPathEmpty() throws Exception {
|
||||
@@ -224,11 +334,12 @@ public class ForwardedHeaderFilterTests {
|
||||
|
||||
@Test
|
||||
public void shouldFilter() {
|
||||
testShouldFilter("Forwarded");
|
||||
testShouldFilter(FORWARDED);
|
||||
testShouldFilter(X_FORWARDED_HOST);
|
||||
testShouldFilter(X_FORWARDED_PORT);
|
||||
testShouldFilter(X_FORWARDED_PROTO);
|
||||
testShouldFilter(X_FORWARDED_SSL);
|
||||
testShouldFilter(X_FORWARDED_FOR);
|
||||
}
|
||||
|
||||
private void testShouldFilter(String headerName) {
|
||||
@@ -249,6 +360,7 @@ public class ForwardedHeaderFilterTests {
|
||||
this.request.addHeader(X_FORWARDED_HOST, "84.198.58.199");
|
||||
this.request.addHeader(X_FORWARDED_PORT, "443");
|
||||
this.request.addHeader("foo", "bar");
|
||||
this.request.addHeader(X_FORWARDED_FOR, "203.0.113.195");
|
||||
|
||||
this.filter.doFilter(this.request, new MockHttpServletResponse(), this.filterChain);
|
||||
HttpServletRequest actual = (HttpServletRequest) this.filterChain.getRequest();
|
||||
@@ -258,10 +370,12 @@ public class ForwardedHeaderFilterTests {
|
||||
assertThat(actual.getServerName()).isEqualTo("84.198.58.199");
|
||||
assertThat(actual.getServerPort()).isEqualTo(443);
|
||||
assertThat(actual.isSecure()).isTrue();
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(actual.getRemoteHost()).isEqualTo("203.0.113.195");
|
||||
|
||||
assertThat(actual.getHeader(X_FORWARDED_PROTO)).isNull();
|
||||
assertThat(actual.getHeader(X_FORWARDED_HOST)).isNull();
|
||||
assertThat(actual.getHeader(X_FORWARDED_PORT)).isNull();
|
||||
assertThat(actual.getHeader(X_FORWARDED_FOR)).isNull();
|
||||
assertThat(actual.getHeader("foo")).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@@ -273,6 +387,7 @@ public class ForwardedHeaderFilterTests {
|
||||
this.request.addHeader(X_FORWARDED_PORT, "443");
|
||||
this.request.addHeader(X_FORWARDED_SSL, "on");
|
||||
this.request.addHeader("foo", "bar");
|
||||
this.request.addHeader(X_FORWARDED_FOR, "203.0.113.195");
|
||||
|
||||
this.filter.setRemoveOnly(true);
|
||||
this.filter.doFilter(this.request, new MockHttpServletResponse(), this.filterChain);
|
||||
@@ -283,11 +398,14 @@ public class ForwardedHeaderFilterTests {
|
||||
assertThat(actual.getServerName()).isEqualTo("localhost");
|
||||
assertThat(actual.getServerPort()).isEqualTo(80);
|
||||
assertThat(actual.isSecure()).isFalse();
|
||||
assertThat(actual.getRemoteAddr()).isEqualTo(MockHttpServletRequest.DEFAULT_REMOTE_ADDR);
|
||||
assertThat(actual.getRemoteHost()).isEqualTo(MockHttpServletRequest.DEFAULT_REMOTE_HOST);
|
||||
|
||||
assertThat(actual.getHeader(X_FORWARDED_PROTO)).isNull();
|
||||
assertThat(actual.getHeader(X_FORWARDED_HOST)).isNull();
|
||||
assertThat(actual.getHeader(X_FORWARDED_PORT)).isNull();
|
||||
assertThat(actual.getHeader(X_FORWARDED_SSL)).isNull();
|
||||
assertThat(actual.getHeader(X_FORWARDED_FOR)).isNull();
|
||||
assertThat(actual.getHeader("foo")).isEqualTo("bar");
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.web.server.adapter;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -35,10 +37,8 @@ public class ForwardedHeaderTransformerTests {
|
||||
|
||||
private static final String BASE_URL = "https://example.com/path";
|
||||
|
||||
|
||||
private final ForwardedHeaderTransformer requestMutator = new ForwardedHeaderTransformer();
|
||||
|
||||
|
||||
@Test
|
||||
void removeOnly() {
|
||||
this.requestMutator.setRemoveOnly(true);
|
||||
@@ -50,6 +50,7 @@ public class ForwardedHeaderTransformerTests {
|
||||
headers.add("X-Forwarded-Proto", "http");
|
||||
headers.add("X-Forwarded-Prefix", "prefix");
|
||||
headers.add("X-Forwarded-Ssl", "on");
|
||||
headers.add("X-Forwarded-For", "203.0.113.195");
|
||||
ServerHttpRequest request = this.requestMutator.apply(getRequest(headers));
|
||||
|
||||
assertForwardedHeadersRemoved(request);
|
||||
@@ -154,6 +155,55 @@ public class ForwardedHeaderTransformerTests {
|
||||
assertForwardedHeadersRemoved(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noForwardedFor() throws URISyntaxException {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Forwarded", "host=84.198.58.199;proto=https");
|
||||
|
||||
InetSocketAddress remoteAddress = new InetSocketAddress("example.client", 47011);
|
||||
|
||||
ServerHttpRequest request = MockServerHttpRequest
|
||||
.method(HttpMethod.GET, new URI("https://example.com/a%20b?q=a%2Bb"))
|
||||
.remoteAddress(remoteAddress)
|
||||
.headers(headers)
|
||||
.build();
|
||||
|
||||
request = this.requestMutator.apply(request);
|
||||
assertThat(request.getRemoteAddress()).isEqualTo(remoteAddress);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forwardedFor() throws URISyntaxException {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Forwarded", "for=\"203.0.113.195:4711\";host=84.198.58.199;proto=https");
|
||||
|
||||
InetSocketAddress remoteAddress = new InetSocketAddress("example.client", 47011);
|
||||
|
||||
ServerHttpRequest request = MockServerHttpRequest
|
||||
.method(HttpMethod.GET, new URI("https://example.com/a%20b?q=a%2Bb"))
|
||||
.remoteAddress(remoteAddress)
|
||||
.headers(headers)
|
||||
.build();
|
||||
|
||||
request = this.requestMutator.apply(request);
|
||||
assertThat(request.getRemoteAddress().getHostName()).isEqualTo("203.0.113.195");
|
||||
assertThat(request.getRemoteAddress().getPort()).isEqualTo(4711);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void xForwardedFor() throws URISyntaxException {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("x-forwarded-for", "203.0.113.195, 70.41.3.18, 150.172.238.178");
|
||||
|
||||
ServerHttpRequest request = MockServerHttpRequest
|
||||
.method(HttpMethod.GET, new URI("https://example.com/a%20b?q=a%2Bb"))
|
||||
.headers(headers)
|
||||
.build();
|
||||
|
||||
request = this.requestMutator.apply(request);
|
||||
assertThat(request.getRemoteAddress().getHostName()).isEqualTo("203.0.113.195");
|
||||
}
|
||||
|
||||
|
||||
private MockServerHttpRequest getRequest(HttpHeaders headers) {
|
||||
return MockServerHttpRequest.get(BASE_URL).headers(headers).build();
|
||||
|
||||
Reference in New Issue
Block a user