Signed-off-by: James Strong <strong.james.e@gmail.com>
This commit is contained in:
parent
59d247dd74
commit
01c9a2bf25
16 changed files with 211 additions and 426 deletions
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||
"k8s.io/ingress-nginx/internal/k8s"
|
||||
"k8s.io/ingress-nginx/internal/net/ssl"
|
||||
"k8s.io/ingress-nginx/pkg/apis/ingress"
|
||||
|
|
@ -30,15 +31,15 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
alphaNumericChars = `A-Za-z0-9\-\.\_\~\/` // This is the default allowed set on paths
|
||||
alphaNumericChars = `\-\.\_\~a-zA-Z0-9/`
|
||||
regexEnabledChars = `\^\$\[\]\(\)\{\}\*\+`
|
||||
)
|
||||
|
||||
var (
|
||||
// pathAlphaNumeric is a regex validation that allows only (0-9, a-z, A-Z, "-", ".", "_", "~", "/")
|
||||
pathAlphaNumericRegex = regexp.MustCompile("^[" + alphaNumericChars + "]*$").MatchString
|
||||
|
||||
// default path type is Prefix to not break existing definitions
|
||||
defaultPathType = networkingv1.PathTypePrefix
|
||||
// pathAlphaNumeric is a regex validation of something like "^/[a-zA-Z]+$" on path
|
||||
pathAlphaNumeric = regexp.MustCompile("^/[" + alphaNumericChars + "]*$").MatchString
|
||||
// pathRegexEnabled is a regex validation of paths that may contain regex.
|
||||
pathRegexEnabled = regexp.MustCompile("^/[" + alphaNumericChars + regexEnabledChars + "]*$").MatchString
|
||||
)
|
||||
|
||||
func GetRemovedHosts(rucfg, newcfg *ingress.Configuration) []string {
|
||||
|
|
@ -246,68 +247,12 @@ func BuildRedirects(servers []*ingress.Server) []*redirect {
|
|||
return redirectServers
|
||||
}
|
||||
|
||||
func ValidateIngressPath(copyIng *networkingv1.Ingress, enablePathTypeValidation bool, pathAdditionalAllowedChars string) error {
|
||||
|
||||
if copyIng == nil {
|
||||
return nil
|
||||
// IsSafePath verifies if the path used in ingress object contains only valid characters.
|
||||
// It will behave differently if regex is enabled or not
|
||||
func IsSafePath(copyIng *networkingv1.Ingress, path string) bool {
|
||||
isRegex, _ := parser.GetBoolAnnotation("use-regex", copyIng)
|
||||
if isRegex {
|
||||
return pathRegexEnabled(path)
|
||||
}
|
||||
|
||||
escapedPathAdditionalAllowedChars := regexp.QuoteMeta(pathAdditionalAllowedChars)
|
||||
regexPath, err := regexp.Compile("^[" + alphaNumericChars + escapedPathAdditionalAllowedChars + "]*$")
|
||||
if err != nil {
|
||||
return fmt.Errorf("ingress has misconfigured validation regex on configmap: %s - %w", pathAdditionalAllowedChars, err)
|
||||
}
|
||||
|
||||
for _, rule := range copyIng.Spec.Rules {
|
||||
|
||||
if rule.HTTP == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := checkPath(rule.HTTP.Paths, enablePathTypeValidation, regexPath); err != nil {
|
||||
return fmt.Errorf("error validating ingressPath: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkPath(paths []networkingv1.HTTPIngressPath, enablePathTypeValidation bool, regexSpecificChars *regexp.Regexp) error {
|
||||
|
||||
for _, path := range paths {
|
||||
if path.PathType == nil {
|
||||
path.PathType = &defaultPathType
|
||||
}
|
||||
|
||||
klog.V(9).InfoS("PathType Validation", "enablePathTypeValidation", enablePathTypeValidation, "regexSpecificChars", regexSpecificChars.String(), "Path", path.Path)
|
||||
|
||||
switch pathType := *path.PathType; pathType {
|
||||
case networkingv1.PathTypeImplementationSpecific:
|
||||
if enablePathTypeValidation {
|
||||
//only match on regex chars per Ingress spec when path is implementation specific
|
||||
if !regexSpecificChars.MatchString(path.Path) {
|
||||
return fmt.Errorf("path %s of type %s contains invalid characters", path.Path, *path.PathType)
|
||||
}
|
||||
}
|
||||
|
||||
case networkingv1.PathTypeExact, networkingv1.PathTypePrefix:
|
||||
//enforce path type validation
|
||||
if enablePathTypeValidation {
|
||||
//only allow alphanumeric chars, no regex chars
|
||||
if !pathAlphaNumericRegex(path.Path) {
|
||||
return fmt.Errorf("path %s of type %s contains invalid characters", path.Path, *path.PathType)
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
//path validation is disabled, so we check what regex chars are allowed by user
|
||||
if !regexSpecificChars.MatchString(path.Path) {
|
||||
return fmt.Errorf("path %s of type %s contains invalid characters", path.Path, *path.PathType)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown path type %v on path %v", *path.PathType, path.Path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return pathAlphaNumeric(path)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue