E5FE Add string validation to server-tokens annotation by shaun-nx · Pull Request #2733 · nginx/kubernetes-ingress · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ Note how the events section includes a Warning event with the Rejected reason.

The following Ingress annotations currently have limited or no validation:

- `nginx.org/server-tokens`,
- `nginx.org/rewrites`,
- `nginx.com/jwt-key`,
- `nginx.com/jwt-realm`,
Expand Down
13 changes: 12 additions & 1 deletion internal/k8s/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package k8s
import (
"errors"
"fmt"
"regexp"
"sort"
"strings"

Expand Down Expand Up @@ -62,7 +63,9 @@ const (
)

const (
commaDelimiter = ","
commaDelimiter = ","
annotationValueFmt = `([^"$\\]|\\[^$])*`
annotationValueFmtErrMsg = `a valid annotation value must have all '"' escaped and must not contain any '$' or end with an unescaped '\'`
)

type annotationValidationContext struct {
Expand All @@ -84,6 +87,8 @@ type (
validatorFunc func(val string) error
)

var validAnnotationValueRegex = regexp.MustCompile("^" + annotationValueFmt + "$")

var (
// annotationValidations defines the various validations which will be applied in order to each ingress annotation.
// If any specified validation fails, the remaining validations for that annotation will not be run.
Expand Down Expand Up @@ -429,11 +434,17 @@ func validateLBMethodAnnotation(context *annotationValidationContext) field.Erro

func validateServerTokensAnnotation(context *annotationValidationContext) field.ErrorList {
allErrs := field.ErrorList{}

if !context.isPlus {
if _, err := configs.ParseBool(context.value); err != nil {
return append(allErrs, field.Invalid(context.fieldPath, context.value, "must be a boolean"))
}
}

if !validAnnotationValueRegex.MatchString(context.value) {
allErrs = append(allErrs, field.Invalid(context.fieldPath, context.value, annotationValueFmtErrMsg))
}

return allErrs
}

Expand Down
42 changes: 42 additions & 0 deletions internal/k8s/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,48 @@ func TestValidateNginxIngressAnnotations(t *testing.T) {
},
msg: "invalid nginx.org/server-tokens annotation, must be a boolean",
},
{
annotations: map[string]string{
"nginx.org/server-tokens": "$custom_setting",
},
specServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
`annotations.nginx.org/server-tokens: Invalid value: "$custom_setting": ` + annotationValueFmtErrMsg,
},
msg: "invalid nginx.org/server-tokens annotation, " + annotationValueFmtErrMsg,
},
{
annotations: map[string]string{
"nginx.org/server-tokens": "custom_\"setting",
},
specServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
`annotations.nginx.org/server-tokens: Invalid value: "custom_\"setting": ` + annotationValueFmtErrMsg,
},
msg: "invalid nginx.org/server-tokens annotation, " + annotationValueFmtErrMsg,
},
{
annotations: map[string]string{
"nginx.org/server-tokens": `custom_setting\`,
},
specServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
`annotations.nginx.org/server-tokens: Invalid value: "custom_setting\\": ` + annotationValueFmtErrMsg,
},
msg: "invalid nginx.org/server-tokens annotation, " + annotationValueFmtErrMsg,
},

{
annotations: map[string]string{
Expand Down
0