From 35ffb9224f09aabb7d5cf2c2ae5fbbcadebbf88a Mon Sep 17 00:00:00 2001 From: "s.v.churanov" Date: Mon, 26 Jan 2026 12:01:57 +0300 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=D1=81orrect=20handling=20of=20multi?= =?UTF-8?q?ple=20X-Forwarded-Host=20values=20Only=20the=20first=20host=20i?= =?UTF-8?q?s=20considered=20according=20to=20RFC=207239?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: s.v.churanov --- pkg/requests/util/util.go | 6 ++++++ pkg/requests/util/util_test.go | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/pkg/requests/util/util.go b/pkg/requests/util/util.go index 290f8059..2dd7e97a 100644 --- a/pkg/requests/util/util.go +++ b/pkg/requests/util/util.go @@ -30,6 +30,12 @@ func GetRequestHost(req *http.Request) string { host := req.Header.Get(XForwardedHost) if !IsProxied(req) || host == "" { host = req.Host + } else { + // Handle multiple hosts in X-Forwarded-Host (comma-separated) + // Take only the first host as per RFC 7239 + if hosts := strings.Split(host, ","); len(hosts) > 0 { + host = strings.TrimSpace(hosts[0]) + } } return host } diff --git a/pkg/requests/util/util_test.go b/pkg/requests/util/util_test.go index ba72c66d..6ae30f47 100644 --- a/pkg/requests/util/util_test.go +++ b/pkg/requests/util/util_test.go @@ -59,6 +59,16 @@ var _ = Describe("Util Suite", func() { req.Header.Add("X-Forwarded-Host", "external.oauth2proxy.text") Expect(util.GetRequestHost(req)).To(Equal("external.oauth2proxy.text")) }) + + It("returns the first X-Forwarded-Host when multiple hosts are present", func() { + req.Header.Add("X-Forwarded-Host", "first.host,second.host,third.host") + Expect(util.GetRequestHost(req)).To(Equal("first.host")) + }) + + It("returns the first X-Forwarded-Host when multiple hosts are present with extra spaces", func() { + req.Header.Add("X-Forwarded-Host", " first.host , second.host , third.host ") + Expect(util.GetRequestHost(req)).To(Equal("first.host")) + }) }) }) From c6ef452c6c6f13f34e1cb0f415f0cd791d038741 Mon Sep 17 00:00:00 2001 From: Jan Larwig Date: Mon, 23 Mar 2026 10:55:34 +0100 Subject: [PATCH 2/3] doc: add changelog entry #3323 Signed-off-by: Jan Larwig Signed-off-by: s.v.churanov --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc4c2379..54041954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ - [#3381](https://github.com/oauth2-proxy/oauth2-proxy/pull/3381) fix: do not log error for backend logout 204 (@artificiosus) - [#3327](https://github.com/oauth2-proxy/oauth2-proxy/pull/3327) fix: improve logging when session refresh token is missing (@yosri-brh) - [#2767](https://github.com/oauth2-proxy/oauth2-proxy/pull/2767) fix: propagate errors during route building (@sybereal) +- [#3323](https://github.com/oauth2-proxy/oauth2-proxy/pull/3323) fix: сorrect handling of multiple X-Forwarded-Host values (@kukubadze) # V7.15.0 From ad9dee617312499a2805615b6d3a557df0cfd0e1 Mon Sep 17 00:00:00 2001 From: "s.v.churanov" Date: Tue, 24 Mar 2026 21:02:54 +0300 Subject: [PATCH 3/3] fix: update comment Signed-off-by: s.v.churanov --- pkg/requests/util/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/requests/util/util.go b/pkg/requests/util/util.go index 2dd7e97a..42963743 100644 --- a/pkg/requests/util/util.go +++ b/pkg/requests/util/util.go @@ -32,7 +32,7 @@ func GetRequestHost(req *http.Request) string { host = req.Host } else { // Handle multiple hosts in X-Forwarded-Host (comma-separated) - // Take only the first host as per RFC 7239 + // Take only the first host as common implementation convention if hosts := strings.Split(host, ","); len(hosts) > 0 { host = strings.TrimSpace(hosts[0]) }