From d32c3163a2600005050c3a579d5979e54e3e7a1e Mon Sep 17 00:00:00 2001 From: Andy Pitcher Date: Fri, 22 Nov 2024 16:22:13 +0100 Subject: [PATCH] Adapt policies.yaml - 5.1.11 typo in sub-resource name 'certificatesigningrequest' https://workbench.cisecurity.org/tickets/21352 - 5.2.2 new audit to verify if a container is privileged or not. https://workbench.cisecurity.org/tickets/20919 - 5.2.3 new audit to verify the presence of hostPID opt-in across all pods. https://workbench.cisecurity.org/tickets/20919 - 5.2.4 new audit to verify the presence of hostIPC opt-in across all pods. https://workbench.cisecurity.org/tickets/20923 - 5.2.5 new audit to verify the presence of hostNetwork opt-in across all pods. https://workbench.cisecurity.org/tickets/20921 - 5.2.6 new audit to verify the presence of 'allowPrivilegeEscalation' to true across all pods' container(s) - 5.2.6 the 'allowPrivilegeEscalation' setting is moved from 'spec' to 'securityContext' https://workbench.cisecurity.org/tickets/20922 --- cfg/cis-1.10/policies.yaml | 128 +++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 6 deletions(-) diff --git a/cfg/cis-1.10/policies.yaml b/cfg/cis-1.10/policies.yaml index 10692f703..7f6b153f2 100644 --- a/cfg/cis-1.10/policies.yaml +++ b/cfg/cis-1.10/policies.yaml @@ -192,7 +192,7 @@ groups: text: "Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)" type: "manual" remediation: | - Where possible, remove access to the approval sub-resource of certificatesigningrequest objects. + Where possible, remove access to the approval sub-resource of certificatesigningrequests objects. scored: false - id: 5.1.12 @@ -222,42 +222,158 @@ groups: - id: 5.2.2 text: "Minimize the admission of privileged containers (Manual)" - type: "manual" + audit: | + kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace + do + # Retrieve container(s) for each Pod. + kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o json | jq -c '.spec.containers[]' | while read -r container + do + # Retrieve container's name. + container_name=$(echo ${container} | jq -r '.name') + # Retrieve container's .securityContext.privileged value. + container_privileged=$(echo ${container} | jq -r '.securityContext.privileged' | sed -e 's/null/notset/g') + if [ "${container_privileged}" = "false" ] || [ "${container_privileged}" = "notset" ] ; then + echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: true" + else + echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: false" + fi + done + done + use_multiple_values: true + tests: + test_items: + - flag: "is_compliant" + compare: + op: eq + value: true remediation: | Add policies to each namespace in the cluster which has user workloads to restrict the admission of privileged containers. + Audit: the audit list all pods' containers to retrieve their .securityContext.privileged value. + Condition: is_compliant is false if container's `.securityContext.privileged` is set to `true`. + Default: by default, there are no restrictions on the creation of privileged containers. scored: false - id: 5.2.3 text: "Minimize the admission of containers wishing to share the host process ID namespace (Manual)" - type: "manual" + audit: | + kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace + do + # Retrieve spec.hostPID for each pod. + pod_hostpid=$(kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o jsonpath='{.spec.hostPID}' 2>/dev/null) + if [ -z "${pod_hostpid}" ]; then + pod_hostpid="false" + echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: true" + else + echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: false" + fi + done + use_multiple_values: true + tests: + test_items: + - flag: "is_compliant" + compare: + op: eq + value: true remediation: | Add policies to each namespace in the cluster which has user workloads to restrict the admission of `hostPID` containers. + Audit: the audit retrieves each Pod' spec.hostPID. + Condition: is_compliant is false if Pod's spec.hostPID is set to `true`. + Default: by default, there are no restrictions on the creation of hostPID containers. scored: false - id: 5.2.4 text: "Minimize the admission of containers wishing to share the host IPC namespace (Manual)" - type: "manual" + audit: | + kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace + do + # Retrieve spec.hostIPC for each pod. + pod_hostipc=$(kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o jsonpath='{.spec.hostIPC}' 2>/dev/null) + if [ -z "${pod_hostipc}" ]; then + pod_hostipc="false" + echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: true" + else + echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: false" + fi + done + use_multiple_values: true + tests: + test_items: + - flag: "is_compliant" + compare: + op: eq + value: true remediation: | Add policies to each namespace in the cluster which has user workloads to restrict the admission of `hostIPC` containers. + Audit: the audit retrieves each Pod' spec.IPC. + Condition: is_compliant is false if Pod's spec.hostIPC is set to `true`. + Default: by default, there are no restrictions on the creation of hostIPC containers. scored: false - id: 5.2.5 text: "Minimize the admission of containers wishing to share the host network namespace (Manual)" - type: "manual" + audit: | + kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace + do + # Retrieve spec.hostNetwork for each pod. + pod_hostnetwork=$(kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o jsonpath='{.spec.hostNetwork}' 2>/dev/null) + if [ -z "${pod_hostnetwork}" ]; then + pod_hostnetwork="false" + echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: true" + else + echo "***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: false" + fi + done + use_multiple_values: true + tests: + test_items: + - flag: "is_compliant" + compare: + op: eq + value: true remediation: | Add policies to each namespace in the cluster which has user workloads to restrict the admission of `hostNetwork` containers. + Audit: the audit retrieves each Pod' spec.hostNetwork. + Condition: is_compliant is false if Pod's spec.hostNetwork is set to `true`. + Default: by default, there are no restrictions on the creation of hostNetwork containers. scored: false - id: 5.2.6 text: "Minimize the admission of containers with allowPrivilegeEscalation (Manual)" - type: "manual" + audit: | + kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace + do + # Retrieve container(s) for each Pod. + kubectl get pod "${pod_name}" --namespace "${pod_namespace}" -o json | jq -c '.spec.containers[]' | while read -r container + do + # Retrieve container's name + container_name=$(echo ${container} | jq -r '.name') + # Retrieve container's .securityContext.allowPrivilegeEscalation + container_allowprivesc=$(echo ${container} | jq -r '.securityContext.allowPrivilegeEscalation' | sed -e 's/null/notset/g') + if [ "${container_allowprivesc}" = "false" ] || [ "${container_allowprivesc}" = "notset" ]; then + echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: true" + else + echo "***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: false" + fi + done + done + use_multiple_values: true + tests: + test_items: + - flag: "is_compliant" + compare: + op: eq + value: true remediation: | Add policies to each namespace in the cluster which has user workloads to restrict the admission of containers with `.spec.allowPrivilegeEscalation` set to `true`. + Audit: the audit retrieves each Pod's container(s) `.spec.allowPrivilegeEscalation`. + Condition: is_compliant is false if container's `.spec.allowPrivilegeEscalation` is set to `true`. + Default: If notset, privilege escalation is allowed (default to true). However if PSP/PSA is used with a `restricted` profile, + privilege escalation is explicitly disallowed unless configured otherwise. scored: false - id: 5.2.7