Skip to content

Commit

Permalink
Merge pull request #1136 from anuddeeph1/CVE-2024-7646
Browse files Browse the repository at this point in the history
Addressing the Latest Kubernetes NGINX Ingress Controller CVE-2024-7646 Vulnerability
  • Loading branch information
realshuting authored Sep 10, 2024
2 parents 30fa4b5 + f89113d commit b72b6bd
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 12 deletions.
24 changes: 12 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(block-pod-exec-by-pod-label|block-pod-exec-by-pod-name|block-stale-images|block-updates-deletes|check-env-vars|check-hpa-exists|check-nvidia-gpu|check-serviceaccount|check-serviceaccount-secrets|check-subjectaccessreview|check-vpa-configuration|concatenate-configmaps)$
tests: ^other$/^(block-pod-exec-by-pod-label|block-pod-exec-by-pod-name|block-stale-images|block-updates-deletes|check-env-vars|check-hpa-exists|check-ingress-nginx-controller-version-and-annotation-policy|check-nvidia-gpu|check-serviceaccount|check-serviceaccount-secrets|check-subjectaccessreview|check-vpa-configuration)$
other-48:
strategy:
fail-fast: false
Expand All @@ -425,7 +425,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(copy-namespace-labels|create-default-pdb|create-pod-antiaffinity|deny-commands-in-exec-probe|deny-secret-service-account-token-type|deployment-replicas-higher-than-pdb|disable-automountserviceaccounttoken|disable-service-discovery|disallow-all-secrets|disallow-localhost-services|disallow-secrets-from-env-vars|dns-policy-and-dns-config)$
tests: ^other$/^(concatenate-configmaps|copy-namespace-labels|create-default-pdb|create-pod-antiaffinity|deny-commands-in-exec-probe|deny-secret-service-account-token-type|deployment-replicas-higher-than-pdb|disable-automountserviceaccounttoken|disable-service-discovery|disallow-all-secrets|disallow-localhost-services|disallow-secrets-from-env-vars)$
other-60:
strategy:
fail-fast: false
Expand All @@ -442,7 +442,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(docker-socket-requires-label|enforce-pod-duration|enforce-resources-as-ratio|ensure-probes-different|ensure-production-matches-staging|ensure-readonly-hostpath|exclude-namespaces-dynamically|forbid-cpu-limits|generate-networkpolicy-existing|get-debug-information|imagepullpolicy-always|ingress-host-match-tls)$
tests: ^other$/^(dns-policy-and-dns-config|docker-socket-requires-label|enforce-pod-duration|enforce-resources-as-ratio|ensure-probes-different|ensure-production-matches-staging|ensure-readonly-hostpath|exclude-namespaces-dynamically|forbid-cpu-limits|generate-networkpolicy-existing|get-debug-information|imagepullpolicy-always)$
other-72:
strategy:
fail-fast: false
Expand All @@ -459,7 +459,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(inject-env-var-from-image-label|inject-sidecar-deployment|inspect-csr|kubernetes-version-check|label-existing-namespaces|label-nodes-cri|limit-configmap-for-sa|limit-containers-per-pod|limit-hostpath-type-pv|limit-hostpath-vols|memory-requests-equal-limits|metadata-match-regex)$
tests: ^other$/^(ingress-host-match-tls|inject-env-var-from-image-label|inject-sidecar-deployment|inspect-csr|kubernetes-version-check|label-existing-namespaces|label-nodes-cri|limit-configmap-for-sa|limit-containers-per-pod|limit-hostpath-type-pv|limit-hostpath-vols|memory-requests-equal-limits)$
other-84:
strategy:
fail-fast: false
Expand All @@ -476,7 +476,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(mitigate-log4shell|mutate-large-termination-gps|mutate-pod-binding|namespace-inventory-check|nfs-subdir-external-provisioner-storage-path|only-trustworthy-registries-set-root|pdb-maxunavailable|pdb-maxunavailable-with-deployments|pdb-minavailable|policy-for-exceptions|prepend-image-registry|prevent-bare-pods)$
tests: ^other$/^(metadata-match-regex|mitigate-log4shell|mutate-large-termination-gps|mutate-pod-binding|namespace-inventory-check|nfs-subdir-external-provisioner-storage-path|only-trustworthy-registries-set-root|pdb-maxunavailable|pdb-maxunavailable-with-deployments|pdb-minavailable|policy-for-exceptions|prepend-image-registry)$
other-96:
strategy:
fail-fast: false
Expand All @@ -493,7 +493,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(prevent-cr8escape|prevent-duplicate-hpa|prevent-duplicate-vpa|protect-node-taints|record-creation-details|refresh-env-var-in-pod|refresh-volumes-in-pods|remove-hostpath-volumes|remove-serviceaccount-token|replace-image-registry|replace-image-registry-with-harbor|replace-ingress-hosts)$
tests: ^other$/^(prevent-bare-pods|prevent-cr8escape|prevent-duplicate-hpa|prevent-duplicate-vpa|protect-node-taints|record-creation-details|refresh-env-var-in-pod|refresh-volumes-in-pods|remove-hostpath-volumes|remove-serviceaccount-token|replace-image-registry|replace-image-registry-with-harbor)$
other-108:
strategy:
fail-fast: false
Expand All @@ -510,7 +510,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(require-annotations|require-base-image|require-container-port-names|require-cpu-limits|require-deployments-have-multiple-replicas|require-emptydir-requests-limits|require-image-checksum|require-image-source|require-imagepullsecrets|require-ingress-https|require-netpol|require-non-root-groups)$
tests: ^other$/^(replace-ingress-hosts|require-annotations|require-base-image|require-container-port-names|require-cpu-limits|require-deployments-have-multiple-replicas|require-emptydir-requests-limits|require-image-checksum|require-image-source|require-imagepullsecrets|require-ingress-https|require-netpol)$
other-120:
strategy:
fail-fast: false
Expand All @@ -527,7 +527,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(require-pdb|require-pod-priorityclassname|require-qos-burstable|require-qos-guaranteed|require-reasonable-pdbs|require-replicas-allow-disruption|require-storageclass|require-unique-external-dns|require-unique-service-selector|require-unique-uid-per-workload|resolve-image-to-digest|resource-creation-updating-denied)$
tests: ^other$/^(require-non-root-groups|require-pdb|require-pod-priorityclassname|require-qos-burstable|require-qos-guaranteed|require-reasonable-pdbs|require-replicas-allow-disruption|require-storageclass|require-unique-external-dns|require-unique-service-selector|require-unique-uid-per-workload|resolve-image-to-digest)$
other-132:
strategy:
fail-fast: false
Expand All @@ -544,7 +544,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(restart-deployment-on-secret-change|restrict-annotations|restrict-automount-sa-token|restrict-binding-clusteradmin|restrict-binding-system-groups|restrict-clusterrole-csr|restrict-clusterrole-mutating-validating-admission-webhooks|restrict-clusterrole-nodesproxy|restrict-controlplane-scheduling|restrict-deprecated-registry|restrict-escalation-verbs-roles|restrict-ingress-classes)$
tests: ^other$/^(resource-creation-updating-denied|restart-deployment-on-secret-change|restrict-annotations|restrict-automount-sa-token|restrict-binding-clusteradmin|restrict-binding-system-groups|restrict-clusterrole-csr|restrict-clusterrole-mutating-validating-admission-webhooks|restrict-clusterrole-nodesproxy|restrict-controlplane-scheduling|restrict-deprecated-registry|restrict-escalation-verbs-roles)$
other-144:
strategy:
fail-fast: false
Expand All @@ -561,7 +561,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(restrict-ingress-defaultbackend|restrict-ingress-host|restrict-ingress-wildcard|restrict-jobs|restrict-loadbalancer|restrict-networkpolicy-empty-podselector|restrict-node-affinity|restrict-node-label-changes|restrict-node-label-creation|restrict-node-selection|restrict-pod-controller-serviceaccount-updates|restrict-sa-automount-sa-token)$
tests: ^other$/^(restrict-ingress-classes|restrict-ingress-defaultbackend|restrict-ingress-host|restrict-ingress-wildcard|restrict-jobs|restrict-loadbalancer|restrict-networkpolicy-empty-podselector|restrict-node-affinity|restrict-node-label-changes|restrict-node-label-creation|restrict-node-selection|restrict-pod-controller-serviceaccount-updates)$
other-156:
strategy:
fail-fast: false
Expand All @@ -578,7 +578,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(restrict-secret-role-verbs|restrict-secrets-by-label|restrict-secrets-by-name|restrict-service-port-range|restrict-storageclass|restrict-usergroup-fsgroup-id|restrict-wildcard-resources|restrict-wildcard-verbs|scale-deployment-zero|spread-pods-across-topology|sync-secrets|topologyspreadconstraints-policy)$
tests: ^other$/^(restrict-sa-automount-sa-token|restrict-secret-role-verbs|restrict-secrets-by-label|restrict-secrets-by-name|restrict-service-port-range|restrict-storageclass|restrict-usergroup-fsgroup-id|restrict-wildcard-resources|restrict-wildcard-verbs|scale-deployment-zero|spread-pods-across-topology|sync-secrets)$
other-168:
strategy:
fail-fast: false
Expand All @@ -595,7 +595,7 @@ jobs:
- name: Run Tests
uses: ./.github/actions/run-tests
with:
tests: ^other$/^(unique-ingress-host-and-path|unique-ingress-paths|update-image-tag|verify-vpa-target)$
tests: ^other$/^(topologyspreadconstraints-policy|unique-ingress-host-and-path|unique-ingress-paths|update-image-tag|verify-vpa-target)$
pod-security_baseline:
strategy:
fail-fast: false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
annotations:
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/server-snippet: |
add_header X-Safe-Header "Safe Content";
add_header X-Vuln-Header "Benign\r
HTTP/1.1 200 OK
Content-Type: text/html
<script>alert('XSS');</script>
--------";
return 200 "Original Content";
spec:
ingressClassName: nginx
rules:
- host: test.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 80
---
apiVersion: v1
kind: Pod
metadata:
name: ingress-nginx-controller
spec:
containers:
- name: controller
image: registry.k8s.io/ingress-nginx/controller:v1.11.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-ingress-nginx-controller-version-and-annotation-policy
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: check-ingress-nginx-controller-version-and-annotation-policy
spec:
steps:
- name: step-01
try:
- apply:
file: ../check-ingress-nginx-controller-version-and-annotation-policy.yaml
- name: step-02
try:
- patch:
resource:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-ingress-nginx-controller-version-and-annotation-policy
spec:
validationFailureAction: Enforce
- assert:
file: chainsaw-step-01-assert-1.yaml
- name: step-03
try:
- apply:
file: good-resource.yaml
- apply:
expect:
- check:
($error != null): true
file: bad-resource.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
annotations:
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
spec:
ingressClassName: nginx
rules:
- host: test.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 80
---
apiVersion: v1
kind: Pod
metadata:
name: ingress-nginx-controller-6bbf7f5879-bvh6l
spec:
containers:
- name: controller
image: registry.k8s.io/ingress-nginx/controller:v1.11.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: check-ingress-nginx-controller-version-and-annotation-policy
version: 1.0.0
displayName: Ensure Valid Ingress NGINX Controller and Annotations
createdAt: "2024-08-26T13:14:30Z"
description: >-
This policy ensures that Ingress resources do not have certain disallowed annotations and that the ingress-nginx controller pod is running an appropriate version of the image. It checks for the presence of the `nginx.ingress.kubernetes.io/server-snippet` annotation and disallows its usage, enforces specific values for `auth-tls-verify-client`, and ensures that the ingress-nginx controller image is of the required version.
install: |-
```shell
kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other/check-ingress-nginx-controller-version-and-annotation-policy/check-ingress-nginx-controller-version-and-annotation-policy.yaml
```
keywords:
- kyverno
- Other
readme: |
This policy ensures that Ingress resources do not have certain disallowed annotations and that the ingress-nginx controller pod is running an appropriate version of the image. It checks for the presence of the `nginx.ingress.kubernetes.io/server-snippet` annotation and disallows its usage, enforces specific values for `auth-tls-verify-client`, and ensures that the ingress-nginx controller image is of the required version.
Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/
annotations:
kyverno/category: "Other"
kyverno/kubernetesVersion: "1.28"
kyverno/subject: "Deployment,ReplicaSet,StatefulSet,DaemonSet,Ingress"
digest: d4bd973c6d8628e8e8944b3bb1df68997cd39c50f18bdbe98c7df6d3942d96da
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-ingress-nginx-controller-version-and-annotation-policy
annotations:
policies.kyverno.io/title: Ensure Valid Ingress NGINX Controller and Annotations
policies.kyverno.io/category: Ingress, Security
policies.kyverno.io/severity: high
kyverno.io/kyverno-version: 1.11.0
policies.kyverno.io/minversion: 1.9.0
kyverno.io/kubernetes-version: "1.28"
policies.kyverno.io/subject: Ingress, Pod
policies.kyverno.io/description: >-
This policy ensures that Ingress resources do not have certain disallowed annotations and that the ingress-nginx
controller Pod is running an appropriate version of the image. It checks for the presence of the
`nginx.ingress.kubernetes.io/server-snippet` annotation and disallows its usage, enforces specific values
for `auth-tls-verify-client`, and ensures that the ingress-nginx controller image is of the required version.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-ingress-annotations
match:
resources:
kinds:
- Ingress
validate:
message: "The annotation nginx.ingress.kubernetes.io/server-snippet is not allowed."
pattern:
metadata:
annotations:
X(nginx.ingress.kubernetes.io/server-snippet): ""
- name: validate-auth-tls-verify-client
match:
resources:
kinds:
- Ingress
validate:
message: "auth-tls-verify-client annotation must be 'on', 'off', 'optional', or 'optional_no_ca'."
deny:
conditions:
any:
- key: "{{request.object.metadata.annotations.\"nginx.ingress.kubernetes.io/auth-tls-verify-client\"}}"
operator: AnyNotIn
value:
- "on"
- "off"
- "optional"
- "optional_no_ca"
- name: ensure-ingress-nginx-controller-version-pattern
match:
resources:
kinds:
- Pod
validate:
message: "The ingress-nginx controller image version must start with v1.11."
pattern:
spec:
containers:
- name: controller
image: "registry.k8s.io/ingress-nginx/controller:v1.11.*"

- name: deny-lower-ingress-nginx-controller-versions
match:
resources:
kinds:
- Pod
validate:
message: "The ingress-nginx controller image version must be v1.11.2 or greater."
deny:
conditions:
- key: "{{ request.object.spec.containers[?(@.name=='controller')].image }}"
operator: AnyIn
value:
- "registry.k8s.io/ingress-nginx/controller:v1.11.0"
- "registry.k8s.io/ingress-nginx/controller:v1.11.1"
- "registry.k8s.io/ingress-nginx/controller:v1.10.*"
- "registry.k8s.io/ingress-nginx/controller:v1.9.*"
- "registry.k8s.io/ingress-nginx/controller:v1.8.*"
- "registry.k8s.io/ingress-nginx/controller:v1.7.*"
- "registry.k8s.io/ingress-nginx/controller:v1.6.*"
- "registry.k8s.io/ingress-nginx/controller:v1.5.*"
- "registry.k8s.io/ingress-nginx/controller:v1.4.*"
- "registry.k8s.io/ingress-nginx/controller:v1.3.*"
- "registry.k8s.io/ingress-nginx/controller:v1.2.*"
- "registry.k8s.io/ingress-nginx/controller:v1.1.*"
- "registry.k8s.io/ingress-nginx/controller:v1.0.*"

0 comments on commit b72b6bd

Please sign in to comment.