spring-cloud / spring-cloud/spring-cloud-gateway
XForwardedHeadersFilter uses wrong remote address for trusted-proxies check
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
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().
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter and trace how request.getRemoteAddress() is populated by the forwarded-header handlers described in the issue. Compare that value with the native request address obtained through ServerHttpRequestDecorator. Done means the trusted-proxies check uses the nearest peer address rather than the transformed client address, with behavior verified for a gateway behind a proxy.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100