From 3f87f91d5064447907b6073315290a28c8eaa6fd Mon Sep 17 00:00:00 2001 From: kooomix Date: Tue, 26 Mar 2024 11:43:25 +0200 Subject: [PATCH 1/2] Fix privilege escalation and privileged container issues Signed-off-by: kooomix --- rules/rule-allow-privilege-escalation/raw.rego | 17 +++++++++++------ .../test/cronjob/expected.json | 15 +++++++++++++-- .../test/workloads/expected.json | 7 ++++++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/rules/rule-allow-privilege-escalation/raw.rego b/rules/rule-allow-privilege-escalation/raw.rego index 41cf0a6f2..9663e9dd9 100644 --- a/rules/rule-allow-privilege-escalation/raw.rego +++ b/rules/rule-allow-privilege-escalation/raw.rego @@ -81,7 +81,9 @@ is_allow_privilege_escalation_container(container, i, start_of_path) = [failed_p psps := [psp | psp= input[_]; psp.kind == "PodSecurityPolicy"] count(psps) == 0 failed_path = "" - fixPath = {"path": sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)]), "value":"false"} + fixPath = [{"path": sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)]), "value":"false"}, + {"path": sprintf("%vcontainers[%v].securityContext.privileged", [start_of_path, format_int(i, 10)]), "value":"false"} + ] } is_allow_privilege_escalation_container(container, i, start_of_path) = [failed_path, fixPath] { @@ -92,7 +94,10 @@ is_allow_privilege_escalation_container(container, i, start_of_path) = [failed_p psp := psps[_] not psp.spec.allowPrivilegeEscalation == false failed_path = "" - fixPath = {"path": sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)]), "value":"false"} + fixPath = [{"path": sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)]), "value":"false"}, + {"path": sprintf("%vcontainers[%v].securityContext.privileged", [start_of_path, format_int(i, 10)]), "value":"false"} + + ] } @@ -101,7 +106,7 @@ is_allow_privilege_escalation_container(container, i, start_of_path) = [failed_p psps := [psp | psp= input[_]; psp.kind == "PodSecurityPolicy"] count(psps) == 0 fixPath = "" - failed_path = sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)]) + failed_path = [sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)])] } is_allow_privilege_escalation_container(container, i, start_of_path)= [failed_path, fixPath] { @@ -111,15 +116,15 @@ is_allow_privilege_escalation_container(container, i, start_of_path)= [failed_pa psp := psps[_] not psp.spec.allowPrivilegeEscalation == false fixPath = "" - failed_path = sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)]) + failed_path = [sprintf("%vcontainers[%v].securityContext.allowPrivilegeEscalation", [start_of_path, format_int(i, 10)])] } - get_failed_path(paths) = [paths[0]] { + get_failed_path(paths) = paths[0] { paths[0] != "" } else = [] -get_fixed_path(paths) = [paths[1]] { +get_fixed_path(paths) = paths[1] { paths[1] != "" } else = [] diff --git a/rules/rule-allow-privilege-escalation/test/cronjob/expected.json b/rules/rule-allow-privilege-escalation/test/cronjob/expected.json index 5e3ef1b1e..e9f6ca325 100644 --- a/rules/rule-allow-privilege-escalation/test/cronjob/expected.json +++ b/rules/rule-allow-privilege-escalation/test/cronjob/expected.json @@ -5,7 +5,12 @@ "fixPaths": [{ "path": "spec.jobTemplate.spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation", "value": "false" - }], + }, + { + "path": "spec.jobTemplate.spec.template.spec.containers[0].securityContext.privileged", + "value": "false" + } +], "ruleStatus": "", "packagename": "armo_builtins", "alertScore": 7, @@ -25,7 +30,13 @@ "fixPaths": [{ "path": "spec.jobTemplate.spec.template.spec.containers[1].securityContext.allowPrivilegeEscalation", "value": "false" - }], + }, + { + "path": "spec.jobTemplate.spec.template.spec.containers[1].securityContext.privileged", + "value": "false" + } + +], "ruleStatus": "", "packagename": "armo_builtins", "alertScore": 7, diff --git a/rules/rule-allow-privilege-escalation/test/workloads/expected.json b/rules/rule-allow-privilege-escalation/test/workloads/expected.json index d8ffd3d4f..f4cdaff01 100644 --- a/rules/rule-allow-privilege-escalation/test/workloads/expected.json +++ b/rules/rule-allow-privilege-escalation/test/workloads/expected.json @@ -25,7 +25,12 @@ "fixPaths": [{ "path": "spec.template.spec.containers[1].securityContext.allowPrivilegeEscalation", "value": "false" - }], + + }, + { + "path": "spec.template.spec.containers[1].securityContext.privileged", + "value": "false" + }], "ruleStatus": "", "packagename": "armo_builtins", "alertScore": 7, From f5e71bae039df2d9570fa29789bd10b40d36d26a Mon Sep 17 00:00:00 2001 From: kooomix Date: Tue, 26 Mar 2024 14:27:43 +0200 Subject: [PATCH 2/2] fix C-0074 Signed-off-by: kooomix --- .../raw.rego | 31 +++++++++++++------ .../test/cronjob-containerd/expected.json | 7 +++-- .../test/cronjob-crio/expected.json | 6 ++-- .../test/cronjob/expected.json | 7 +++-- .../test/pod-containerd/expected.json | 6 ++-- .../test/pod-crio/expected.json | 6 ++-- .../test/pod/expected.json | 6 ++-- .../test/workloads-containerd/expected.json | 4 +-- .../test/workloads-crio/expected.json | 4 +-- .../test/workloads/expected.json | 4 +-- 10 files changed, 54 insertions(+), 27 deletions(-) diff --git a/rules/containers-mounting-docker-socket/raw.rego b/rules/containers-mounting-docker-socket/raw.rego index 9c74778af..b52a6b453 100644 --- a/rules/containers-mounting-docker-socket/raw.rego +++ b/rules/containers-mounting-docker-socket/raw.rego @@ -7,12 +7,15 @@ deny[msga] { volume := pod.spec.volumes[i] host_path := volume.hostPath is_runtime_socket_mounting(host_path) - path := sprintf("spec.volumes[%v].hostPath.path", [format_int(i, 10)]) + path := sprintf("spec.volumes[%v]", [format_int(i, 10)]) + volumeMounts := pod.spec.containers[j].volumeMounts + pathMounts = volume_mounts(volume.name, volumeMounts, sprintf("spec.containers[%v]", [j])) + finalPath := array.concat([path], pathMounts) msga := { "alertMessage": sprintf("volume: %v in pod: %v has mounting to Docker internals.", [volume.name, pod.metadata.name]), "packagename": "armo_builtins", - "deletePaths": [path], - "failedPaths": [path], + "deletePaths":finalPath, + "failedPaths": finalPath, "fixPaths":[], "alertScore": 5, "alertObject": { @@ -30,12 +33,15 @@ deny[msga] { volume := wl.spec.template.spec.volumes[i] host_path := volume.hostPath is_runtime_socket_mounting(host_path) - path := sprintf("spec.template.spec.volumes[%v].hostPath.path", [format_int(i, 10)]) + path := sprintf("spec.template.spec.volumes[%v]", [format_int(i, 10)]) + volumeMounts := wl.spec.template.spec.containers[j].volumeMounts + pathMounts = volume_mounts(volume.name,volumeMounts, sprintf("spec.template.spec.containers[%v]", [j])) + finalPath := array.concat([path], pathMounts) msga := { "alertMessage": sprintf("volume: %v in %v: %v has mounting to Docker internals.", [ volume.name, wl.kind, wl.metadata.name]), "packagename": "armo_builtins", - "deletePaths": [path], - "failedPaths": [path], + "deletePaths": finalPath, + "failedPaths": finalPath, "fixPaths":[], "alertScore": 5, "alertObject": { @@ -51,12 +57,15 @@ deny[msga] { volume = wl.spec.jobTemplate.spec.template.spec.volumes[i] host_path := volume.hostPath is_runtime_socket_mounting(host_path) - path := sprintf("spec.jobTemplate.spec.template.spec.volumes[%v].hostPath.path", [format_int(i, 10)]) + path := sprintf("spec.jobTemplate.spec.template.spec.volumes[%v]", [format_int(i, 10)]) + volumeMounts := wl.spec.jobTemplate.spec.template.spec.containers[j].volumeMounts + pathMounts = volume_mounts(volume.name,volumeMounts, sprintf("spec.jobTemplate.spec.template.spec.containers[%v]", [j])) + finalPath := array.concat([path], pathMounts) msga := { "alertMessage": sprintf("volume: %v in %v: %v has mounting to Docker internals.", [ volume.name, wl.kind, wl.metadata.name]), "packagename": "armo_builtins", - "deletePaths": [path], - "failedPaths": [path], + "deletePaths": finalPath, + "failedPaths": finalPath, "fixPaths":[], "alertScore": 5, "alertObject": { @@ -65,6 +74,10 @@ deny[msga] { } } +volume_mounts(name, volume_mounts, str) = [path] { + name == volume_mounts[j].name + path := sprintf("%s.volumeMounts[%v]", [str, j]) +} else = [] is_runtime_socket_mounting(host_path) { host_path.path == "/var/run/docker.sock" diff --git a/rules/containers-mounting-docker-socket/test/cronjob-containerd/expected.json b/rules/containers-mounting-docker-socket/test/cronjob-containerd/expected.json index 436eb3bfc..f87bbe7f8 100644 --- a/rules/containers-mounting-docker-socket/test/cronjob-containerd/expected.json +++ b/rules/containers-mounting-docker-socket/test/cronjob-containerd/expected.json @@ -2,10 +2,13 @@ { "alertMessage": "volume: test-volume in CronJob: hello has mounting to Docker internals.", "deletePaths": [ - "spec.jobTemplate.spec.template.spec.volumes[0].hostPath.path" + "spec.jobTemplate.spec.template.spec.volumes[0]", + "spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0]" + ], "failedPaths": [ - "spec.jobTemplate.spec.template.spec.volumes[0].hostPath.path" + "spec.jobTemplate.spec.template.spec.volumes[0]", + "spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/cronjob-crio/expected.json b/rules/containers-mounting-docker-socket/test/cronjob-crio/expected.json index 436eb3bfc..b14f08fb7 100644 --- a/rules/containers-mounting-docker-socket/test/cronjob-crio/expected.json +++ b/rules/containers-mounting-docker-socket/test/cronjob-crio/expected.json @@ -2,10 +2,12 @@ { "alertMessage": "volume: test-volume in CronJob: hello has mounting to Docker internals.", "deletePaths": [ - "spec.jobTemplate.spec.template.spec.volumes[0].hostPath.path" + "spec.jobTemplate.spec.template.spec.volumes[0]", + "spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0]" ], "failedPaths": [ - "spec.jobTemplate.spec.template.spec.volumes[0].hostPath.path" + "spec.jobTemplate.spec.template.spec.volumes[0]", + "spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/cronjob/expected.json b/rules/containers-mounting-docker-socket/test/cronjob/expected.json index 436eb3bfc..f87bbe7f8 100644 --- a/rules/containers-mounting-docker-socket/test/cronjob/expected.json +++ b/rules/containers-mounting-docker-socket/test/cronjob/expected.json @@ -2,10 +2,13 @@ { "alertMessage": "volume: test-volume in CronJob: hello has mounting to Docker internals.", "deletePaths": [ - "spec.jobTemplate.spec.template.spec.volumes[0].hostPath.path" + "spec.jobTemplate.spec.template.spec.volumes[0]", + "spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0]" + ], "failedPaths": [ - "spec.jobTemplate.spec.template.spec.volumes[0].hostPath.path" + "spec.jobTemplate.spec.template.spec.volumes[0]", + "spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/pod-containerd/expected.json b/rules/containers-mounting-docker-socket/test/pod-containerd/expected.json index 602a58262..86e5dda70 100644 --- a/rules/containers-mounting-docker-socket/test/pod-containerd/expected.json +++ b/rules/containers-mounting-docker-socket/test/pod-containerd/expected.json @@ -2,10 +2,12 @@ { "alertMessage": "volume: test-volume in pod: test-pd has mounting to Docker internals.", "deletePaths": [ - "spec.volumes[0].hostPath.path" + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" ], "failedPaths": [ - "spec.volumes[0].hostPath.path" + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/pod-crio/expected.json b/rules/containers-mounting-docker-socket/test/pod-crio/expected.json index 602a58262..86e5dda70 100644 --- a/rules/containers-mounting-docker-socket/test/pod-crio/expected.json +++ b/rules/containers-mounting-docker-socket/test/pod-crio/expected.json @@ -2,10 +2,12 @@ { "alertMessage": "volume: test-volume in pod: test-pd has mounting to Docker internals.", "deletePaths": [ - "spec.volumes[0].hostPath.path" + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" ], "failedPaths": [ - "spec.volumes[0].hostPath.path" + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/pod/expected.json b/rules/containers-mounting-docker-socket/test/pod/expected.json index 602a58262..86e5dda70 100644 --- a/rules/containers-mounting-docker-socket/test/pod/expected.json +++ b/rules/containers-mounting-docker-socket/test/pod/expected.json @@ -2,10 +2,12 @@ { "alertMessage": "volume: test-volume in pod: test-pd has mounting to Docker internals.", "deletePaths": [ - "spec.volumes[0].hostPath.path" + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" ], "failedPaths": [ - "spec.volumes[0].hostPath.path" + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/workloads-containerd/expected.json b/rules/containers-mounting-docker-socket/test/workloads-containerd/expected.json index e142cca61..17d23ad59 100644 --- a/rules/containers-mounting-docker-socket/test/workloads-containerd/expected.json +++ b/rules/containers-mounting-docker-socket/test/workloads-containerd/expected.json @@ -2,10 +2,10 @@ { "alertMessage": "volume: test-volume2 in Deployment: my-deployment has mounting to Docker internals.", "deletePaths": [ - "spec.template.spec.volumes[1].hostPath.path" + "spec.template.spec.volumes[1]" ], "failedPaths": [ - "spec.template.spec.volumes[1].hostPath.path" + "spec.template.spec.volumes[1]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/workloads-crio/expected.json b/rules/containers-mounting-docker-socket/test/workloads-crio/expected.json index e142cca61..17d23ad59 100644 --- a/rules/containers-mounting-docker-socket/test/workloads-crio/expected.json +++ b/rules/containers-mounting-docker-socket/test/workloads-crio/expected.json @@ -2,10 +2,10 @@ { "alertMessage": "volume: test-volume2 in Deployment: my-deployment has mounting to Docker internals.", "deletePaths": [ - "spec.template.spec.volumes[1].hostPath.path" + "spec.template.spec.volumes[1]" ], "failedPaths": [ - "spec.template.spec.volumes[1].hostPath.path" + "spec.template.spec.volumes[1]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/containers-mounting-docker-socket/test/workloads/expected.json b/rules/containers-mounting-docker-socket/test/workloads/expected.json index e142cca61..17d23ad59 100644 --- a/rules/containers-mounting-docker-socket/test/workloads/expected.json +++ b/rules/containers-mounting-docker-socket/test/workloads/expected.json @@ -2,10 +2,10 @@ { "alertMessage": "volume: test-volume2 in Deployment: my-deployment has mounting to Docker internals.", "deletePaths": [ - "spec.template.spec.volumes[1].hostPath.path" + "spec.template.spec.volumes[1]" ], "failedPaths": [ - "spec.template.spec.volumes[1].hostPath.path" + "spec.template.spec.volumes[1]" ], "fixPaths": [], "ruleStatus": "",