diff --git a/controls/symlinkexchangecanallowhostfilesystemaccess.json b/controls/symlinkexchangecanallowhostfilesystemaccess.json new file mode 100644 index 000000000..6773bca8e --- /dev/null +++ b/controls/symlinkexchangecanallowhostfilesystemaccess.json @@ -0,0 +1,12 @@ +{ + "name": "Symlink Exchange Can Allow Host Filesystem Access (CVE-2021-25741)", + "attributes": { + "armoBuiltin": true + }, + "description": "A security issue was discovered in Kubernetes where a user may be able to create a container with subPath volume mounts to access files & directories outside of the volume, including on the host filesystem. This was affected at the following versions: v1.22.0 - v1.22.1, v1.21.0 - v1.21.4, v1.20.0 - v1.20.10, version v1.19.14 and lower.", + "remediation": "To mitigate this vulnerability without upgrading kubelet, you can disable the VolumeSubpath feature gate on kubelet and kube-apiserver, and remove any existing Pods making use of the feature.", + "rulesNames": [ + "Symlink-Exchange-Can-Allow-Host-Filesystem-Access" + ], + "id": "C-0058" +} \ No newline at end of file diff --git a/frameworks/MITRE.json b/frameworks/MITRE.json index 78e583950..1f0ae51be 100644 --- a/frameworks/MITRE.json +++ b/frameworks/MITRE.json @@ -32,6 +32,7 @@ "Delete Kubernetes events", "CoreDNS poisoning", "Data Destruction", - "Resource Hijacking" + "Resource Hijacking", + "Symlink Exchange Can Allow Host Filesystem Access (CVE-2021-25741)" ] } diff --git a/frameworks/NSAframework.json b/frameworks/NSAframework.json index 850d707aa..51b2cb3d3 100644 --- a/frameworks/NSAframework.json +++ b/frameworks/NSAframework.json @@ -24,6 +24,7 @@ "Linux hardening", "Ingress and Egress blocked", "Container hostPort", - "Network policies" + "Network policies", + "Symlink Exchange Can Allow Host Filesystem Access (CVE-2021-25741)" ] } diff --git a/rules/CVE-2021-25741/raw.rego b/rules/CVE-2021-25741/raw.rego new file mode 100644 index 000000000..5f5cfa1c7 --- /dev/null +++ b/rules/CVE-2021-25741/raw.rego @@ -0,0 +1,88 @@ +package armo_builtins + + +deny[msga] { + nodes := input[_] + current_version := nodes.status.nodeInfo.kubeletVersion + isVulnerableVersion(current_version) + pod := input[_] + pod.kind == "Pod" + container := pod.spec.containers[_] + isSubPathContainer(container) + + msga := { + "alertMessage": sprintf("You may be vulnerable to CVE-2021-25741. You have a Node with version: %v and the following container : %v in pod : %v with subPath/subPathExpr", [current_version, container.name, pod.metadata.name]), + "alertObject": {"k8SApiObjects": [nodes, pod]}, + } +} + + +deny[msga] { + nodes := input[_] + current_version := nodes.status.nodeInfo.kubeletVersion + isVulnerableVersion(current_version) + wl := input[_] + spec_template_spec_patterns := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"} + spec_template_spec_patterns[wl.kind] + container := wl.spec.template.spec.containers[_] + isSubPathContainer(container) + + msga := { + "alertMessage": sprintf("You may be vulnerable to CVE-2021-25741. You have a Node with version: %v and the following container : %v in %v : %v with subPath/subPathExpr", [current_version, container.name, wl.kind, wl.metadata.name]), + "alertObject": {"k8SApiObjects": [nodes, wl]}, + } +} + + + +deny[msga] { + nodes := input[_] + current_version := nodes.status.nodeInfo.kubeletVersion + isVulnerableVersion(current_version) + wl := input[_] + wl.kind == "CronJob" + container = wl.spec.jobTemplate.spec.template.spec.containers[_] + isSubPathContainer(container) + + msga := { + "alertMessage": sprintf("You may be vulnerable to CVE-2021-25741. You have a Node with version: %v and the following container : %v in %v : %v with subPath/subPathExpr", [current_version, container.name, wl.kind, wl.metadata.name]), + "alertObject": {"k8SApiObjects": [nodes, wl]}, + } +} + + + +isSubPathContainer(container){ + container.volumeMounts[_].subPath +} + +isSubPathContainer(container){ + container.volumeMounts[_].subPathExpr +} + +isVulnerableVersion(version){ + version <= "v1.19.14" +} + +isVulnerableVersion(version){ + version >= "v1.22.0" + version <= "v1.22.1" +} + + +isVulnerableVersion(version){ + version >= "v1.21.0" + version <= "v1.21.4" +} + + +isVulnerableVersion(version){ + version >= "v1.20.0" + version <= "v1.20.9" +} + +isVulnerableVersion(version){ + version == "v1.20.10" +} + + diff --git a/rules/CVE-2021-25741/rule.metadata.json b/rules/CVE-2021-25741/rule.metadata.json new file mode 100644 index 000000000..f981bd9fc --- /dev/null +++ b/rules/CVE-2021-25741/rule.metadata.json @@ -0,0 +1,32 @@ +{ + "name": "Symlink-Exchange-Can-Allow-Host-Filesystem-Access", + "attributes": { + "armoBuiltin": true + }, + "ruleLanguage": "Rego", + "match": [ + { + "apiGroups": [ + "*" + ], + "apiVersions": [ + "*" + ], + "resources": [ + "Deployment", + "ReplicaSet", + "DaemonSet", + "StatefulSet", + "Job", + "Pod", + "CronJob", + "Node" + ] + } + ], + "ruleDependencies": [ + ], + "description": "A security issue was discovered in Kubernetes where a user may be able to create a container with subPath volume mounts to access files & directories outside of the volume, including on the host filesystem. This was affected at the following versions: v1.22.0 - v1.22.1, v1.21.0 - v1.21.4, v1.20.0 - v1.20.10, version v1.19.14 and lower.", + "remediation": "To mitigate this vulnerability without upgrading kubelet, you can disable the VolumeSubpath feature gate on kubelet and kube-apiserver, and remove any existing Pods making use of the feature.", + "ruleQuery": "armo_builtins" +} \ No newline at end of file