Browse Source

fix(s3api): correctly extract host header port in extractHostHeader (#8464)

* Prevent concurrent maintenance tasks per volume

* fix panic

* fix(s3api): correctly extract host header port when X-Forwarded-Port is present

* test(s3api): add test cases for misreported X-Forwarded-Port
pull/8360/merge
Chris Lu 1 day ago
committed by GitHub
parent
commit
e8946e59ca
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 25
      weed/s3api/auth_signature_v4.go
  2. 25
      weed/s3api/auth_signature_v4_test.go

25
weed/s3api/auth_signature_v4.go

@ -828,29 +828,32 @@ func extractHostHeader(r *http.Request, externalHost string) string {
} else { } else {
host = strings.TrimSpace(forwardedHost) host = strings.TrimSpace(forwardedHost)
} }
// Baseline port from forwarded port if available
if forwardedPort != "" {
port = forwardedPort
}
// If the host itself contains a port, it should take precedence // If the host itself contains a port, it should take precedence
if h, p, err := net.SplitHostPort(host); err == nil { if h, p, err := net.SplitHostPort(host); err == nil {
host = h host = h
port = p port = p
} else {
// If X-Forwarded-Host has no port, try to get port from r.Host if hostnames match
if rh, rp, err := net.SplitHostPort(r.Host); err == nil && rh == host {
port = rp
} else if forwardedPort != "" {
port = forwardedPort
}
} }
} else { } else {
host = r.Host host = r.Host
if host == "" { if host == "" {
host = r.URL.Host host = r.URL.Host
} }
// Also apply X-Forwarded-Port in the fallback path
if forwardedPort != "" {
if h, _, err := net.SplitHostPort(host); err == nil {
host = h
}
port = forwardedPort
} else if h, p, err := net.SplitHostPort(host); err == nil {
// If the host already contains a port, use it.
// Otherwise, if X-Forwarded-Port is set, use it.
if h, p, err := net.SplitHostPort(host); err == nil {
host = h host = h
port = p port = p
} else if forwardedPort != "" {
port = forwardedPort
} }
} }

25
weed/s3api/auth_signature_v4_test.go

@ -364,6 +364,31 @@ func TestExtractHostHeader(t *testing.T) {
externalHost: "[::1]:9000", externalHost: "[::1]:9000",
expected: "[::1]:9000", expected: "[::1]:9000",
}, },
// Bug fix: X-Forwarded-Port should not override more specific ports in other headers
{
name: "User reported case: X-Forwarded-Port misreports 443 but Host has 30007",
hostHeader: "storage-stgops.mt.mtnet:30007",
forwardedHost: "storage-stgops.mt.mtnet",
forwardedPort: "443",
forwardedProto: "https",
expected: "storage-stgops.mt.mtnet:30007",
},
{
name: "X-Forwarded-Host already contains correct port, ignore misaligned X-Forwarded-Port",
hostHeader: "backend:8333",
forwardedHost: "storage-stgops.mt.mtnet:30007",
forwardedPort: "443",
forwardedProto: "https",
expected: "storage-stgops.mt.mtnet:30007",
},
{
name: "X-Forwarded-Host has no port, match r.Host hostname and take its port",
hostHeader: "example.com:8080",
forwardedHost: "example.com",
forwardedPort: "80",
forwardedProto: "http",
expected: "example.com:8080",
},
} }
for _, tt := range tests { for _, tt := range tests {

Loading…
Cancel
Save