8000 Sanitize nginx.com/jwt-token by haywoodsh · Pull Request #2774 · 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
19 changes: 17 additions & 2 deletions internal/k8s/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,19 @@ const (
commaDelimiter = ","
annotationValueFmt = `([^"$\\]|\\[^$])*`
pathFmt = `/[^\s{};]*`
jwtTokenValueFmt = "\\$" + annotationValueFmt
)

const (
annotationValueFmtErrMsg = `a valid annotation value must have all '"' escaped and must not contain any '$' or end with an unescaped '\'`
pathErrMsg = "must start with / and must not include any whitespace character, `{`, `}` or `;`"
jwtTokenValueFmtErrMsg = `a valid annotation value must start with '$', have all '"' escaped, and must not contain any '$' or end with an unescaped '\'`
)

var (
validAnnotationValueRegex = regexp.MustCompile("^" + annotationValueFmt + "$")
pathRegexp = regexp.MustCompile("^" + pathFmt + "$")
pathRegexp = regexp.MustCompile("^" + pathFmt + "$")
validAnnotationValueRegex = regexp.MustCompile("^" + annotationValueFmt + "$")
validJWTTokenAnnotationValueRegex = regexp.MustCompile("^" + jwtTokenValueFmt + "$")
)

type annotationValidationContext struct {
Expand Down Expand Up @@ -222,6 +225,7 @@ var (
},
jwtTokenAnnotation: {
validatePlusOnlyAnnotation,
validateJWTTokenAnnotation,
},
jwtLoginURLAnnotation: {
validatePlusOnlyAnnotation,
Expand Down Expand Up @@ -339,6 +343,17 @@ func validateJWTRealm(context *annotationValidationContext) field.ErrorList {
return allErrs
}

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

if !validJWTTokenAnnotationValueRegex.MatchString(context.value) {
msg := validation.RegexError(jwtTokenValueFmtErrMsg, jwtTokenValueFmt, "$http_token", "$cookie_auth_token")
allErrs = append(allErrs, field.Invalid(context.fieldPath, context.value, msg))
}

return allErrs
}

func validateHTTPHeadersAnnotation(context *annotationValidationContext) field.ErrorList {
var allErrs field.ErrorList
headers := strings.Split(context.value, commaDelimiter)
Expand Down
69 changes: 69 additions & 0 deletions internal/k8s/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,75 @@ func TestValidateNginxIngressAnnotations(t *testing.T) {
expectedErrors: nil,
msg: "valid nginx.com/jwt-token annotation",
},
{
annotations: map[string]string{
"nginx.com/jwt-token": "cookie_auth_token",
},
specServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
"annotations.nginx.com/jwt-token: Invalid value: \"cookie_auth_token\": a valid annotation value must start with '$', have all '\"' escaped, and must not contain any '$' or end with an unescaped '\\' (e.g. '$http_token', or '$cookie_auth_token', regex used for validation is '\\$([^\"$\\\\]|\\\\[^$])*')",
}, msg: "invalid nginx.com/jwt-token annotation, '$' missing",
},
{
annotations: map[string]string{
"nginx.com/jwt-token": `$cookie_auth_token"`,
},
specServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
"annotations.nginx.com/jwt-token: Invalid value: \"$cookie_auth_token\\\"\": a valid annotation value must start with '$', have all '\"' escaped, and must not contain any '$' or end with an unescaped '\\' (e.g. '$http_token', or '$cookie_auth_token', regex used for validation is '\\$([^\"$\\\\]|\\\\[^$])*')",
},
msg: "invalid nginx.com/jwt-token annotation, containing unescaped '\"'",
},
{
annotations: map[string]string{
"nginx.com/jwt-token": `$cookie_auth_token\`,
},
sp 9E12 ecServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
"annotations.nginx.com/jwt-token: Invalid value: \"$cookie_auth_token\\\\\": a valid annotation value must start with '$', have all '\"' escaped, and must not contain any '$' or end with an unescaped '\\' (e.g. '$http_token', or '$cookie_auth_token', regex used for validation is '\\$([^\"$\\\\]|\\\\[^$])*')",
},
msg: "invalid nginx.com/jwt-token annotation, containing escape characters",
},
{
annotations: map[string]string{
"nginx.com/jwt-token": "cookie_auth$token",
},
specServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
"annotations.nginx.com/jwt-token: Invalid value: \"cookie_auth$token\": a valid annotation value must start with '$', have all '\"' escaped, and must not contain any '$' or end with an unescaped '\\' (e.g. '$http_token', or '$cookie_auth_token', regex used for validation is '\\$([^\"$\\\\]|\\\\[^$])*')",
},
msg: "invalid nginx.com/jwt-token annotation, containing incorrect variable",
},
{
annotations: map[string]string{
"nginx.com/jwt-token": "$cookie_auth_token$http_token",
},
specServices: map[string]bool{},
isPlus: true,
appProtectEnabled: false,
appProtectDosEnabled: false,
internalRoutesEnabled: false,
expectedErrors: []string{
"annotations.nginx.com/jwt-token: Invalid value: \"$cookie_auth_token$http_token\": a valid annotation value must start with '$', have all '\"' escaped, and must not contain any '$' or end with an unescaped '\\' (e.g. '$http_token', or '$cookie_auth_token', regex used for validation is '\\$([^\"$\\\\]|\\\\[^$])*')",
},
msg: "invalid nginx.com/jwt-token annotation, containing more than 1 variable",
},

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