Skip to content

XForwardedHeadersFilter uses wrong remote address for trusted-proxies check #4074

@Dmitrii-Grigorev3

Description

@Dmitrii-Grigorev3

The org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter uses request.getRemoteAddress() to match with the trustedProxies. This incorrect, because getRemoteAddress() returns something you didn't expect.

Problem:
When the gateway is behind a proxy (e.g. in a cloud), the remote address visible on ServerHttpRequest is often already overwritten to the client IP from X-Forwarded-For (or from the Forwarded header), so it is not the nearest proxy. That overwriting, depends on forward-headers-strategy configuration, can happen in:

  • DefaultNettyHttpForwardedHeaderHandler, which in turn uses parseXForwardedInfo / parseForwardedInfo and overwrites the connection’s remote address with the left-most (client) IP from the XFF header.

    left-most ip from XFF it is a client ip according to the https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For
    X-Forwarded-For: client, proxy, …, proxyN

  • org.springframework.web.server.adapter.ForwardedHeaderTransformer, which is uses ForwardedHeaderUtils to parse left-most ip from the XFF header and sets as a remote address

       * Parse the first "Forwarded: for=..." or "X-Forwarded-For" header value to
       * an {@code InetSocketAddress} representing the address of the client.
      remoteAddress = ForwardedHeaderUtils.parseForwardedFor(originalUri, headers, remoteAddress);
      if (remoteAddress != null) {
          	builder.remoteAddress(remoteAddress);
      }
      
    

So by the time XForwardedHeadersFilter runs, request.getRemoteAddress() is often the client IP, not the nearest proxy. Using it for “is the direct peer trusted?” is incorrect.

Solution:

We could get the real remote (peer) address using ServerHttpRequestDecorator.getNativeRequest(request).getRemoteAddress().

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions