Skip to content

ForwardedHeadersFilter: wrong mapping for IPv6 remote address #2214

Closed
@hhwidera

Description

@hhwidera

Hi,
I see a problem with IPv6 remote addresses and the org.springframework.cloud.gateway.filter.headers.ForwardedHeadersFilter.
When a remote address is in IPv6 format then in the Forwarded header I miss the '[' and ']' around the IPv6 address (see https://tools.ietf.org/html/rfc7239).

Example:
For '2001:db8:cafe:0:0:0:0:17' and port 4711 the result header should include 'for="[2001:db8:cafe:0:0:0:0:17]:4711"' but I see only 'for="2001:db8:cafe:0:0:0:0:17:4711"' (missing '[' and ']' around the IPv6 address).

Possible test:

public class ForwardedHeadersFilterTests {

	...

	@Test
	public void correctIPv6RemoteAddressMapping() throws UnknownHostException {
		MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost/get")
				.remoteAddress(new InetSocketAddress(InetAddress.getByName("2001:db8:cafe:0:0:0:0:17"), 80))
				.header(HttpHeaders.HOST, "myhost").build();

		ForwardedHeadersFilter filter = new ForwardedHeadersFilter();

		HttpHeaders headers = filter.filter(request.getHeaders(), MockServerWebExchange.from(request));

		assertThat(headers.get(FORWARDED_HEADER)).hasSize(1);

		List<Forwarded> forwardeds = ForwardedHeadersFilter.parse(headers.get(FORWARDED_HEADER));

		assertThat(forwardeds).hasSize(1);
		Forwarded forwarded = forwardeds.get(0);

		assertThat(forwarded.getValues()).containsEntry("for", "\"[2001:db8:cafe:0:0:0:0:17]:80\"");
	}

Possible fix:

public class ForwardedHeadersFilter implements HttpHeadersFilter, Ordered {

	...

	@Override
	public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) {

		... 

		URI uri = request.getURI();
		String host = original.getFirst(HttpHeaders.HOST);
		Forwarded forwarded = new Forwarded().put("host", host).put("proto", uri.getScheme());

		InetSocketAddress remoteAddress = request.getRemoteAddress();
		if (remoteAddress != null) {
			// If remoteAddress is unresolved, calling getHostAddress() would cause a
			// NullPointerException.
			String forValue;
			if (remoteAddress.isUnresolved()) {
				forValue = remoteAddress.getHostName();
			} else {
				InetAddress address = remoteAddress.getAddress();
				forValue = remoteAddress.getAddress().getHostAddress();
				if (address instanceof Inet6Address) {
					forValue = "[" + forValue + "]";
				}
			}
			int port = remoteAddress.getPort();
			if (port >= 0) {
				forValue = forValue + ":" + port;
			}
			forwarded.put("for", forValue);
		}
		// TODO: support by?

		updated.add(FORWARDED_HEADER, forwarded.toHeaderValue());

		return updated;
	}

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions