diff --git a/internal/ingress/annotations/authreqglobal/main.go b/internal/ingress/annotations/authreqglobal/main.go index a931d0bbd..6032dc595 100644 --- a/internal/ingress/annotations/authreqglobal/main.go +++ b/internal/ingress/annotations/authreqglobal/main.go @@ -71,4 +71,4 @@ func (a authReqGlobal) GetDocumentation() parser.AnnotationFields { func (a authReqGlobal) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, globalAuthAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/authtls/main.go b/internal/ingress/annotations/authtls/main.go index 2c47a14ff..53ee83fa8 100644 --- a/internal/ingress/annotations/authtls/main.go +++ b/internal/ingress/annotations/authtls/main.go @@ -219,4 +219,4 @@ func (a authTLS) GetDocumentation() parser.AnnotationFields { func (a authTLS) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, authTLSAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/canary/main.go b/internal/ingress/annotations/canary/main.go index 866f3a834..9e688a118 100644 --- a/internal/ingress/annotations/canary/main.go +++ b/internal/ingress/annotations/canary/main.go @@ -192,4 +192,4 @@ func (c canary) GetDocumentation() parser.AnnotationFields { func (a canary) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, CanaryAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/clientbodybuffersize/main.go b/internal/ingress/annotations/clientbodybuffersize/main.go index 025db96f1..61094d0c6 100644 --- a/internal/ingress/annotations/clientbodybuffersize/main.go +++ b/internal/ingress/annotations/clientbodybuffersize/main.go @@ -68,4 +68,4 @@ func (cbbs clientBodyBufferSize) Parse(ing *networking.Ingress) (interface{}, er func (a clientBodyBufferSize) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, clientBodyBufferSizeConfig.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/connection/main.go b/internal/ingress/annotations/connection/main.go index 4cca6a94f..eaf83b4e0 100644 --- a/internal/ingress/annotations/connection/main.go +++ b/internal/ingress/annotations/connection/main.go @@ -104,4 +104,4 @@ func (a connection) GetDocumentation() parser.AnnotationFields { func (a connection) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, connectionHeadersAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/cors/main.go b/internal/ingress/annotations/cors/main.go index 8698588d4..442e70158 100644 --- a/internal/ingress/annotations/cors/main.go +++ b/internal/ingress/annotations/cors/main.go @@ -263,4 +263,4 @@ func (c cors) GetDocumentation() parser.AnnotationFields { func (a cors) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, corsAnnotation.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/defaultbackend/main.go b/internal/ingress/annotations/defaultbackend/main.go index f413b4bab..0dae64905 100644 --- a/internal/ingress/annotations/defaultbackend/main.go +++ b/internal/ingress/annotations/defaultbackend/main.go @@ -79,4 +79,4 @@ func (db backend) GetDocumentation() parser.AnnotationFields { func (a backend) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, defaultBackendAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/fastcgi/main.go b/internal/ingress/annotations/fastcgi/main.go index 2cc20444c..ec4feec66 100644 --- a/internal/ingress/annotations/fastcgi/main.go +++ b/internal/ingress/annotations/fastcgi/main.go @@ -164,4 +164,4 @@ func (a fastcgi) GetDocumentation() parser.AnnotationFields { func (a fastcgi) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, fastCGIAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/globalratelimit/main.go b/internal/ingress/annotations/globalratelimit/main.go index 0bd9dad9c..c8803dada 100644 --- a/internal/ingress/annotations/globalratelimit/main.go +++ b/internal/ingress/annotations/globalratelimit/main.go @@ -177,4 +177,4 @@ func (a globalratelimit) GetDocumentation() parser.AnnotationFields { func (a globalratelimit) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, globalRateLimitAnnotationConfig.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/http2pushpreload/main.go b/internal/ingress/annotations/http2pushpreload/main.go index f9bc2f0f8..36441c301 100644 --- a/internal/ingress/annotations/http2pushpreload/main.go +++ b/internal/ingress/annotations/http2pushpreload/main.go @@ -65,4 +65,4 @@ func (h2pp http2PushPreload) GetDocumentation() parser.AnnotationFields { func (a http2PushPreload) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, http2PushPreloadAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/ipallowlist/main.go b/internal/ingress/annotations/ipallowlist/main.go index 270e265c0..f2fb2cb81 100644 --- a/internal/ingress/annotations/ipallowlist/main.go +++ b/internal/ingress/annotations/ipallowlist/main.go @@ -130,4 +130,4 @@ func (a ipallowlist) GetDocumentation() parser.AnnotationFields { func (a ipallowlist) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, allowlistAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/ipdenylist/main.go b/internal/ingress/annotations/ipdenylist/main.go index 0d8885401..37bd7ad50 100644 --- a/internal/ingress/annotations/ipdenylist/main.go +++ b/internal/ingress/annotations/ipdenylist/main.go @@ -127,4 +127,4 @@ func (a ipdenylist) GetDocumentation() parser.AnnotationFields { func (a ipdenylist) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, denylistAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/loadbalancing/main.go b/internal/ingress/annotations/loadbalancing/main.go index 80bbdb489..0191981a4 100644 --- a/internal/ingress/annotations/loadbalancing/main.go +++ b/internal/ingress/annotations/loadbalancing/main.go @@ -71,4 +71,4 @@ func (a loadbalancing) GetDocumentation() parser.AnnotationFields { func (a loadbalancing) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, loadBalanceAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/log/main.go b/internal/ingress/annotations/log/main.go index 97779475e..3649ecd6a 100644 --- a/internal/ingress/annotations/log/main.go +++ b/internal/ingress/annotations/log/main.go @@ -104,4 +104,4 @@ func (l log) GetDocumentation() parser.AnnotationFields { func (a log) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, logAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/mirror/main.go b/internal/ingress/annotations/mirror/main.go index bd4effa71..14a14e324 100644 --- a/internal/ingress/annotations/mirror/main.go +++ b/internal/ingress/annotations/mirror/main.go @@ -165,4 +165,4 @@ func (a mirror) GetDocumentation() parser.AnnotationFields { func (a mirror) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, mirrorAnnotation.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/modsecurity/main.go b/internal/ingress/annotations/modsecurity/main.go index 004b9ae6e..97120eac7 100644 --- a/internal/ingress/annotations/modsecurity/main.go +++ b/internal/ingress/annotations/modsecurity/main.go @@ -157,4 +157,4 @@ func (a modSecurity) GetDocumentation() parser.AnnotationFields { func (a modSecurity) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, modsecurityAnnotation.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/opentelemetry/main.go b/internal/ingress/annotations/opentelemetry/main.go index 3add51a34..24f34ae4b 100644 --- a/internal/ingress/annotations/opentelemetry/main.go +++ b/internal/ingress/annotations/opentelemetry/main.go @@ -153,4 +153,4 @@ func (c opentelemetry) GetDocumentation() parser.AnnotationFields { func (a opentelemetry) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, otelAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/opentracing/main.go b/internal/ingress/annotations/opentracing/main.go index 4bce34cba..c8fc71d65 100644 --- a/internal/ingress/annotations/opentracing/main.go +++ b/internal/ingress/annotations/opentracing/main.go @@ -110,4 +110,4 @@ func (s opentracing) GetDocumentation() parser.AnnotationFields { func (a opentracing) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, opentracingAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/portinredirect/main.go b/internal/ingress/annotations/portinredirect/main.go index 10f2c3d79..0e51ee0f4 100644 --- a/internal/ingress/annotations/portinredirect/main.go +++ b/internal/ingress/annotations/portinredirect/main.go @@ -70,4 +70,4 @@ func (a portInRedirect) GetDocumentation() parser.AnnotationFields { func (a portInRedirect) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, portsInRedirectAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/proxy/main.go b/internal/ingress/annotations/proxy/main.go index fe7f66cbe..120a99830 100644 --- a/internal/ingress/annotations/proxy/main.go +++ b/internal/ingress/annotations/proxy/main.go @@ -361,4 +361,4 @@ func (a proxy) GetDocumentation() parser.AnnotationFields { func (a proxy) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, proxyAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/proxyssl/main.go b/internal/ingress/annotations/proxyssl/main.go index 07b5dbcfc..254996926 100644 --- a/internal/ingress/annotations/proxyssl/main.go +++ b/internal/ingress/annotations/proxyssl/main.go @@ -263,4 +263,4 @@ func (p proxySSL) GetDocumentation() parser.AnnotationFields { func (a proxySSL) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, proxySSLAnnotation.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/ratelimit/main.go b/internal/ingress/annotations/ratelimit/main.go index 12b426eb7..38940203a 100644 --- a/internal/ingress/annotations/ratelimit/main.go +++ b/internal/ingress/annotations/ratelimit/main.go @@ -298,4 +298,4 @@ func (a ratelimit) GetDocumentation() parser.AnnotationFields { func (a ratelimit) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, rateLimitAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/redirect/redirect.go b/internal/ingress/annotations/redirect/redirect.go index 1cbcc4e8c..9300271eb 100644 --- a/internal/ingress/annotations/redirect/redirect.go +++ b/internal/ingress/annotations/redirect/redirect.go @@ -181,4 +181,4 @@ func (a redirect) GetDocumentation() parser.AnnotationFields { func (a redirect) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, redirectAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/rewrite/main.go b/internal/ingress/annotations/rewrite/main.go index debd6e0f7..1134e27b1 100644 --- a/internal/ingress/annotations/rewrite/main.go +++ b/internal/ingress/annotations/rewrite/main.go @@ -212,4 +212,4 @@ func (a rewrite) GetDocumentation() parser.AnnotationFields { func (a rewrite) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, rewriteAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/satisfy/main.go b/internal/ingress/annotations/satisfy/main.go index dc0b25a6a..d74fb33f5 100644 --- a/internal/ingress/annotations/satisfy/main.go +++ b/internal/ingress/annotations/satisfy/main.go @@ -72,4 +72,4 @@ func (s satisfy) GetDocumentation() parser.AnnotationFields { func (a satisfy) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, satisfyAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/serversnippet/main.go b/internal/ingress/annotations/serversnippet/main.go index 3360a7dc3..b6693c1d9 100644 --- a/internal/ingress/annotations/serversnippet/main.go +++ b/internal/ingress/annotations/serversnippet/main.go @@ -66,4 +66,4 @@ func (a serverSnippet) GetDocumentation() parser.AnnotationFields { func (a serverSnippet) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, serverSnippetAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/serviceupstream/main.go b/internal/ingress/annotations/serviceupstream/main.go index ca069dc1c..7692ffe86 100644 --- a/internal/ingress/annotations/serviceupstream/main.go +++ b/internal/ingress/annotations/serviceupstream/main.go @@ -72,4 +72,4 @@ func (s serviceUpstream) GetDocumentation() parser.AnnotationFields { func (a serviceUpstream) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, serviceUpstreamAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/sessionaffinity/main.go b/internal/ingress/annotations/sessionaffinity/main.go index ea9fe9924..07d737de3 100644 --- a/internal/ingress/annotations/sessionaffinity/main.go +++ b/internal/ingress/annotations/sessionaffinity/main.go @@ -301,4 +301,4 @@ func (a affinity) GetDocumentation() parser.AnnotationFields { func (a affinity) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, sessionAffinityAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/snippet/main.go b/internal/ingress/annotations/snippet/main.go index 851962544..6b75ff440 100644 --- a/internal/ingress/annotations/snippet/main.go +++ b/internal/ingress/annotations/snippet/main.go @@ -66,4 +66,4 @@ func (a snippet) GetDocumentation() parser.AnnotationFields { func (a snippet) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, configurationSnippetAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/sslcipher/main.go b/internal/ingress/annotations/sslcipher/main.go index 30f9cf822..a1a316d57 100644 --- a/internal/ingress/annotations/sslcipher/main.go +++ b/internal/ingress/annotations/sslcipher/main.go @@ -107,4 +107,4 @@ func (sc sslCipher) GetDocumentation() parser.AnnotationFields { func (a sslCipher) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, sslCipherAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/sslpassthrough/main.go b/internal/ingress/annotations/sslpassthrough/main.go index 2635136ed..45007b7f7 100644 --- a/internal/ingress/annotations/sslpassthrough/main.go +++ b/internal/ingress/annotations/sslpassthrough/main.go @@ -69,4 +69,4 @@ func (a sslpt) GetDocumentation() parser.AnnotationFields { func (a sslpt) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, sslPassthroughAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/streamsnippet/main.go b/internal/ingress/annotations/streamsnippet/main.go index 2d69c4b2c..da5a9a142 100644 --- a/internal/ingress/annotations/streamsnippet/main.go +++ b/internal/ingress/annotations/streamsnippet/main.go @@ -66,4 +66,4 @@ func (a streamSnippet) GetDocumentation() parser.AnnotationFields { func (a streamSnippet) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, streamSnippetAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/upstreamhashby/main.go b/internal/ingress/annotations/upstreamhashby/main.go index a111ffd41..825961883 100644 --- a/internal/ingress/annotations/upstreamhashby/main.go +++ b/internal/ingress/annotations/upstreamhashby/main.go @@ -111,4 +111,4 @@ func (a upstreamhashby) GetDocumentation() parser.AnnotationFields { func (a upstreamhashby) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, upstreamHashByAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/upstreamvhost/main.go b/internal/ingress/annotations/upstreamvhost/main.go index 1c779366d..028e62939 100644 --- a/internal/ingress/annotations/upstreamvhost/main.go +++ b/internal/ingress/annotations/upstreamvhost/main.go @@ -67,4 +67,4 @@ func (a upstreamVhost) GetDocumentation() parser.AnnotationFields { func (a upstreamVhost) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, upstreamVhostAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/annotations/xforwardedprefix/main.go b/internal/ingress/annotations/xforwardedprefix/main.go index 2b60cb3cf..0986295b3 100644 --- a/internal/ingress/annotations/xforwardedprefix/main.go +++ b/internal/ingress/annotations/xforwardedprefix/main.go @@ -65,4 +65,4 @@ func (cbbs xforwardedprefix) GetDocumentation() parser.AnnotationFields { func (a xforwardedprefix) Validate(anns map[string]string) error { maxrisk := parser.StringRiskToRisk(a.r.GetSecurityConfiguration().AnnotationsRisk) return parser.CheckAnnotationRisk(anns, maxrisk, xForwardedForAnnotations.Annotations) -} \ No newline at end of file +} diff --git a/internal/ingress/errors/errors.go b/internal/ingress/errors/errors.go index 5809c96ac..e6f7fb52c 100644 --- a/internal/ingress/errors/errors.go +++ b/internal/ingress/errors/errors.go @@ -115,6 +115,10 @@ type ValidationError struct { Reason error } +type RiskyAnnotationError struct { + Reason error +} + func (e ValidationError) Error() string { return e.Reason.Error() } @@ -132,3 +136,21 @@ func IsValidationError(e error) bool { _, ok := e.(ValidationError) return ok } + +// NewValidationError returns a new LocationDenied error +func NewRiskyAnnotations(name string) error { + return RiskyAnnotationError{ + Reason: fmt.Errorf("annotation group %s contains risky annotation based on ingress configuration", name), + } +} + +// IsRiskyAnnotationError checks if the err is an error which +// indicates that some annotation value is invalid +func IsRiskyAnnotationError(e error) bool { + _, ok := e.(ValidationError) + return ok +} + +func (e RiskyAnnotationError) Error() string { + return e.Reason.Error() +} diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go index 489e24886..d5f95597c 100644 --- a/pkg/flags/flags.go +++ b/pkg/flags/flags.go @@ -152,6 +152,9 @@ Requires the update-status parameter.`) annotationsPrefix = flags.String("annotations-prefix", parser.DefaultAnnotationsPrefix, `Prefix of the Ingress annotations specific to the NGINX controller.`) + disableAnnotationValidation = flags.Bool("disable-annotation-validation", parser.DefaultDisableAnnotationValidation, + `Prefix of the Ingress annotations specific to the NGINX controller.`) + enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", false, `Autocomplete SSL certificate chains with missing intermediate CA certificates. Certificates uploaded to Kubernetes must have the "Authority Information Access" X.509 v3 @@ -249,6 +252,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g } parser.AnnotationsPrefix = *annotationsPrefix + parser.DisableAnnotationValidation = *disableAnnotationValidation // check port collisions if !ing_net.IsPortAvailable(*httpPort) { diff --git a/test/e2e-image/namespace-overlays/validations/values.yaml b/test/e2e-image/namespace-overlays/validations/values.yaml new file mode 100644 index 000000000..d423217db --- /dev/null +++ b/test/e2e-image/namespace-overlays/validations/values.yaml @@ -0,0 +1,38 @@ +# TODO: remove the need to use fullnameOverride +fullnameOverride: nginx-ingress +controller: + image: + repository: ingress-controller/controller + chroot: true + tag: 1.0.0-dev + digest: + digestChroot: + containerPort: + http: "1080" + https: "1443" + + extraArgs: + http-port: "1080" + https-port: "1443" + # e2e tests do not require information about ingress status + update-status: "false" + + scope: + enabled: true + + config: + worker-processes: "1" + service: + type: NodePort + + admissionWebhooks: + enabled: true + certificate: "/usr/local/certificates/cert" + key: "/usr/local/certificates/key" + +defaultBackend: + enabled: false + +rbac: + create: true + scope: true diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index f9bfb18a4..28adf297d 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -47,7 +47,7 @@ import ( _ "k8s.io/ingress-nginx/test/e2e/settings" _ "k8s.io/ingress-nginx/test/e2e/settings/modsecurity" _ "k8s.io/ingress-nginx/test/e2e/settings/ocsp" - // _ "k8s.io/ingress-nginx/test/e2e/settings/validations" // Test is not working, need to check the cross namespace stuff + _ "k8s.io/ingress-nginx/test/e2e/settings/validations" _ "k8s.io/ingress-nginx/test/e2e/ssl" _ "k8s.io/ingress-nginx/test/e2e/status" diff --git a/test/e2e/settings/validations/validations.go b/test/e2e/settings/validations/validations.go index 47d5ff439..2163ff3e1 100644 --- a/test/e2e/settings/validations/validations.go +++ b/test/e2e/settings/validations/validations.go @@ -18,93 +18,69 @@ package annotations import ( "context" - "fmt" - "net/http" - "strings" "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" - "golang.org/x/crypto/bcrypt" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/test/e2e/framework" ) -func buildSecret(username, password, name, namespace string) *corev1.Secret { - //out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput() - out, err := bcrypt.GenerateFromPassword([]byte(password), 14) - encpass := fmt.Sprintf("%v:%s\n", username, out) - assert.Nil(ginkgo.GinkgoT(), err) +var _ = framework.IngressNginxDescribeSerial("annotation validations", func() { + f := framework.NewDefaultFramework("validations") - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - DeletionGracePeriodSeconds: framework.NewInt64(1), - }, - Data: map[string][]byte{ - "auth": []byte(encpass), - }, - Type: corev1.SecretTypeOpaque, - } -} - -var _ = framework.DescribeAnnotation("annotation validations", func() { - f := framework.NewDefaultFramework("annotations-validations") - - ginkgo.BeforeEach(func() { - f.NewEchoDeployment() - otherns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "otherns", - }, - } - _, err := f.KubeClientSet.CoreV1().Namespaces().Create(context.Background(), otherns, metav1.CreateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "creating namespace") - }) - - ginkgo.AfterEach(func() { - err := f.KubeClientSet.CoreV1().Namespaces().Delete(context.Background(), "otherns", metav1.DeleteOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "deleting namespace") - }) - - ginkgo.It("should return status code 401 when authentication is configured but Authorization header is not configured", func() { + ginkgo.It("should allow ingress based on their risk on webhooks", func() { host := "annotation-validations" - // Allow cross namespace consumption - f.UpdateNginxConfigMapData("allow-cross-namespace-resources", "true") + + // Low and Medium Risk annotations should be allowed, the rest should be denied + f.UpdateNginxConfigMapData("annotations-risk", "Medium") // Sleep a while just to guarantee that the configmap is applied framework.Sleep() - s := f.EnsureSecret(buildSecret("foo", "bar", "test", "otherns")) - annotations := map[string]string{ - "nginx.ingress.kubernetes.io/auth-type": "basic", - "nginx.ingress.kubernetes.io/auth-secret": fmt.Sprintf("%s/%s", s.Namespace, s.Name), - "nginx.ingress.kubernetes.io/auth-realm": "test auth", + "nginx.ingress.kubernetes.io/default-backend": "default/bla", // low risk + "nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk } + ginkgo.By("allow ingress with low/medium risk annotations") ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - f.EnsureIngress(ing) + _, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), ing, metav1.CreateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err, "creating ingress with allowed annotations should not trigger an error") - f.WaitForNginxServer(host, - func(server string) bool { - return strings.Contains(server, "server_name annotation-validations") - }) + ginkgo.By("block ingress with risky annotations") + annotations["nginx.ingress.kubernetes.io/modsecurity-transaction-id"] = "bla123" // High should be blocked + annotations["nginx.ingress.kubernetes.io/modsecurity-snippet"] = "some random stuff;" // High should be blocked + ing = framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) + _, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) + assert.NotNil(ginkgo.GinkgoT(), err, "creating ingress with risky annotations should trigger an error") - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusUnauthorized). - Body().Contains("401 Authorization Required") + }) + + ginkgo.It("should allow ingress based on their risk on webhooks", func() { + host := "annotation-validations" + + // Low and Medium Risk annotations should be allowed, the rest should be denied + f.UpdateNginxConfigMapData("annotations-risk", "Medium") + // Sleep a while just to guarantee that the configmap is applied + framework.Sleep() + + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/default-backend": "default/bla", // low risk + "nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk + } + + ginkgo.By("allow ingress with low/medium risk annotations") + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) + _, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), ing, metav1.CreateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err, "creating ingress with allowed annotations should not trigger an error") + + ginkgo.By("block ingress with risky annotations") + annotations["nginx.ingress.kubernetes.io/modsecurity-transaction-id"] = "bla123" // High should be blocked + annotations["nginx.ingress.kubernetes.io/modsecurity-snippet"] = "some random stuff;" // High should be blocked + ing = framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) + _, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) + assert.NotNil(ginkgo.GinkgoT(), err, "creating ingress with risky annotations should trigger an error") - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - WithBasicAuth("foo", "bar"). - Expect(). - Status(http.StatusOK) }) })