Skip to content

Commit 7a7e356

Browse files
committed
Disallow host header in proxy-set-header annotation
1 parent 375d405 commit 7a7e356

2 files changed

Lines changed: 44 additions & 0 deletions

File tree

internal/k8s/validation.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,12 @@ func validateProxySetHeaderAnnotation(context *annotationValidationContext) fiel
710710
continue
711711
}
712712

713+
// Host must be set via the dedicated nginx.org/upstream-vhost annotation
714+
if strings.EqualFold(name, "Host") {
715+
allErrs = append(allErrs, field.Invalid(context.fieldPath, name, "the Host header must be set using the nginx.org/upstream-vhost annotation"))
716+
continue
717+
}
718+
713719
for _, msg := range version1.ValidateAddHeaderName(name) {
714720
allErrs = append(allErrs, field.Invalid(context.fieldPath, name, msg))
715721
}

internal/k8s/validation_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5729,6 +5729,7 @@ func TestValidateProxySetHeaderAnnotation(t *testing.T) {
57295729
t.Parallel()
57305730

57315731
headerNameErrMsg := `a valid HTTP header must consist of alphanumeric characters or '-' (e.g. 'X-Header-Name', regex used for validation is '[-A-Za-z0-9]+')`
5732+
disallowedHostErrMsg := `the Host header must be set using the nginx.org/upstream-vhost annotation`
57325733

57335734
tests := []struct {
57345735
name string
@@ -5853,6 +5854,43 @@ func TestValidateProxySetHeaderAnnotation(t *testing.T) {
58535854
},
58545855
},
58555856

5857+
// ── Invalid: disallowed header names ────────────────────────────
5858+
{
5859+
name: "disallowed header - Host name only",
5860+
value: "Host",
5861+
expectedErrors: []string{
5862+
`annotations.nginx.org/proxy-set-headers: Invalid value: "Host": ` + disallowedHostErrMsg,
5863+
},
5864+
},
5865+
{
5866+
name: "disallowed header - Host with value",
5867+
value: "Host: example.internal",
5868+
expectedErrors: []string{
5869+
`annotations.nginx.org/proxy-set-headers: Invalid value: "Host": ` + disallowedHostErrMsg,
5870+
},
5871+
},
5872+
{
5873+
name: "disallowed header - lowercase host",
5874+
value: "host: example.internal",
5875+
expectedErrors: []string{
5876+
`annotations.nginx.org/proxy-set-headers: Invalid value: "host": ` + disallowedHostErrMsg,
5877+
},
5878+
},
5879+
{
5880+
name: "disallowed header - uppercase HOST",
5881+
value: "HOST: example.internal",
5882+
expectedErrors: []string{
5883+
`annotations.nginx.org/proxy-set-headers: Invalid value: "HOST": ` + disallowedHostErrMsg,
5884+
},
5885+
},
5886+
{
5887+
name: "disallowed header mixed with valid headers",
5888+
value: "Header-1,Host: example.internal,Header-2",
5889+
expectedErrors: []string{
5890+
`annotations.nginx.org/proxy-set-headers: Invalid value: "Host": ` + disallowedHostErrMsg,
5891+
},
5892+
},
5893+
58565894
// ── Invalid: spaces without colon (caught by IsHTTPHeaderName) ─
58575895
{
58585896
name: "invalid header name with spaces and no colon",

0 commit comments

Comments
 (0)