-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http/httputil: add X-Forwarded-Proto and X-Forwarded-Host by default #50465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
We don't want to add special-purpose APIs when general-purpose ones suffice. We also don't want to add knobs to enable the right behavior; if the default behavior of I think it makes sense to add It might make sense to add the RFC 7239 It is probable that appending to an existing I just filed #50580 to address an unrelated issue, which proposes replacing the To summarize:
|
From my experience, almost all tools support XFF headers, but only a few support
I'm the author of this documentation. This behavior was not documented, which was/is probably a security vulnerability. If this works for you, I'll update my patch to only keep the addition of |
/cc @neild |
This proposal has been added to the active column of the proposals project |
So if
If the idea comes around to automatically appending or overwriting depending if a source is trusted or not, there will need to be configuration available to indicate what's "trusted". (For some setups it will just be "ip.IsPrivate() => trusted". For others using Cloudflare or the like it'll need to be a list of IP ranges.) (I'm not a big fan of overwriting the XFF list, as there are some legitimate non-security uses for the leftmost-ish XFF IP. Completely taking that option away from users seems unfortunate. On the other hand using the leftmost for security-related purposes is a big, widespread problem. So maybe taking the option away from users is a sufficient overall improvement that the loss of flexibility is justified.) ETA: If you're overwriting XFF, then nine out of ten times you should just be setting a single-IP header like X-Real-IP instead. |
It seems clear that ReverseProxy is not right in certain contexts, but we don't know the right path forward for it. Perhaps the right next step is to put this on hold (or decline it) and suggest that people fork ReverseProxy and experiment in their own copies? |
It seems like we should decline this until we have a clearer idea of a path forward (or a new package). |
Actually, on Jan 12, @neild wrote
Should we make that a separate proposal? Or should we make this proposal be about that? |
If we make the proposal about that, I can easily adapt the patch to do this. |
Retitled. Does anyone object to adding X-Forwarded-Proto and X-Forwarded-Host by default? |
Based on the discussion above, this proposal seems like a likely accept. |
No change in consensus, so accepted. 🎉 |
I'll update #36678 according to the accepted proposal. |
Change https://go.dev/cl/407414 mentions this issue: |
see golang/go#50465 PiperOrigin-RevId: 469184819 Change-Id: I05a5c6a59b788e769c2c85b5f27efabbdc4e2629
Change https://go.dev/cl/450515 mentions this issue: |
For #41773 For #41773 For #50465 For #51914 For #53002 For #53896 For #53960 For #54136 For #54299 Change-Id: I729d5eafc1940d5706f980882a08ece1f69bb42c Reviewed-on: https://go-review.googlesource.com/c/go/+/450515 Auto-Submit: Damien Neil <dneil@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
Change https://go.dev/cl/457595 mentions this issue: |
…Director funcs This reverts CL 407414. When forwarding an inbound request that contains an existing X-Forwarded-Host or X-Forwarded-Proto header, a proxy might want to preserve the header from the inbound request, replace it with its own header, or not include any header at all. CL 407414 replaces inbound X-Forwarded-{Host,Proto} headers by default, and allows a Director func to disable sending these headers at all. However, the Director hook API isn't sufficiently flexible to permit the previous behavior of preserving inbound values unchanged. The new Rewrite API does have this flexibility; users of Rewrite can easily pick the exact behavior they want. Revert the change to ReverseProxy when using a Director func. Users who want a convenient way to set X-Forwarded-* headers to reasonable values can migrate to Rewrite at their convenience, and users depending on the current behavior will be unaffected. For #50465. Fixes #57132. Change-Id: Ic42449c1bb525d6c9920bf721efbc519697f4f20 Reviewed-on: https://go-review.googlesource.com/c/go/+/457595 Run-TryBot: Damien Neil <dneil@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
Go's HTTP
ReverseProxy
has basic forwarded headers support, but this support is incomplete and can even be dangerous:X-Forwarded-For
is set automatically, if the request already contains anX-Forwarded-For
header, the client IP is added to the existing header values (the IPs of the previous proxies in the chain). This behavior was undocumented, and already led to IP spoofing vulnerabilities. I documented this behavior in net/http/httputil: add docs about X-Forwarded-For in ReverseProxy #36672. Vulnerable projects created before the documentation was added probably exist in the wild.X-Forwarded-For
is automatically set,X-Forwarded-Proto
andX-Forwarded-Host
are not, which is weird.X-Forwarded-For
support is not obvious, and looks hackish: you have to manually delete the potentially existing header before forwarding the request. Edit: you can now usenil
to prevent the header to be set: net/http/httputil: do not add to empty X-Forwarded-For header in ReverseProxy #38079X-Forwarded-For
is supported, the standardForwarded
header (RFC 7239) isn't.I propose to add two new public fields to the
ReverseProxy
struct to control the behavior regarding forwarded headers:This is technically a BC break, as the default behavior will now be to overwrite the existing
X-Forwarded-*
headers, whereas currently the client IP is added (usually unexpectedly) to the existing values ofX-Forwarded-For
. But in my opinion, it is worth it to harden the API and prevent security issues. If this BC break is unacceptable, we can reverse the order ofForwardedHeaderOverwrite
andForwardedHeaderAdd
(but the default insecure behavior will persist).Supporting the legacy XFF headers is necessary because currently most of the ecosystem only supports these. The standardized version hasn't been widely adopted so far.
Adding support for the standardized header will require more work as it will probably require writing a custom parser. I suggest implementing support for
ForwardedHeaderBehavior
first to fix the current behavior, and adding support forForwardedHeaderFormat
later.I already drafted a patch implementing the first part: #36678.
The text was updated successfully, but these errors were encountered: