diff --git a/rules/alert-mount-potential-credentials-paths/raw.rego b/rules/alert-mount-potential-credentials-paths/raw.rego index f28c15776..68e476863 100644 --- a/rules/alert-mount-potential-credentials-paths/raw.rego +++ b/rules/alert-mount-potential-credentials-paths/raw.rego @@ -6,18 +6,22 @@ deny[msga] { provider := data.dataControlInputs.cloudProvider provider != "" resources := input[_] - volumes_data := get_volumes(resources) - volumes := volumes_data["volumes"] + spec_data := get_pod_spec(resources) + spec := spec_data["spec"] + volumes := spec.volumes volume := volumes[i] - start_of_path := volumes_data["start_of_path"] - result := is_unsafe_paths(volume, start_of_path, provider,i) + start_of_path := spec_data["start_of_path"] + result := is_unsafe_paths(volume, start_of_path, provider, i) + volumeMounts := spec.containers[j].volumeMounts + pathMounts = volume_mounts(volume.name, volumeMounts, sprintf("%vcontainers[%d]", [start_of_path, j])) + finalPath := array.concat([result], pathMounts) msga := { "alertMessage": sprintf("%v: %v has: %v as volume with potential credentials access.", [resources.kind, resources.metadata.name, volume.name]), "packagename": "armo_builtins", "alertScore": 7, - "deletePaths": [result], - "failedPaths": [result], + "deletePaths": finalPath, + "failedPaths": finalPath, "fixPaths":[], "alertObject": { "k8sApiObjects": [resources] @@ -25,24 +29,23 @@ deny[msga] { } } - -# get_volume - get resource volumes paths for {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"} -get_volumes(resources) := result { +# get_volume - get resource spec paths for {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"} +get_pod_spec(resources) := result { resources_kinds := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"} resources_kinds[resources.kind] - result = {"volumes": resources.spec.template.spec.volumes, "start_of_path": "spec.template.spec."} + result = {"spec": resources.spec.template.spec, "start_of_path": "spec.template.spec."} } -# get_volume - get resource volumes paths for "Pod" -get_volumes(resources) := result { +# get_volume - get resource spec paths for "Pod" +get_pod_spec(resources) := result { resources.kind == "Pod" - result = {"volumes": resources.spec.volumes, "start_of_path": "spec."} + result = {"spec": resources.spec, "start_of_path": "spec."} } -# get_volume - get resource volumes paths for "CronJob" -get_volumes(resources) := result { +# get_volume - get resource spec paths for "CronJob" +get_pod_spec(resources) := result { resources.kind == "CronJob" - result = {"volumes": resources.spec.jobTemplate.spec.template.spec.volumes, "start_of_path": "spec.jobTemplate.spec.template.spec."} + result = {"spec": resources.spec.jobTemplate.spec.template.spec, "start_of_path": "spec.jobTemplate.spec.template.spec."} } @@ -50,7 +53,7 @@ get_volumes(resources) := result { is_unsafe_paths(volume, start_of_path, provider, i) = result { unsafe := unsafe_paths(provider) unsafe[_] == fix_path(volume.hostPath.path) - result= sprintf("%vvolumes[%d].hostPath.path", [start_of_path, i]) + result = sprintf("%vvolumes[%d]", [start_of_path, i]) } @@ -89,3 +92,7 @@ unsafe_paths(x) := ["/.config/gcloud/", "/.config/gcloud/application_default_credentials.json", "/gcloud/application_default_credentials.json"] if {x=="gke"} +volume_mounts(name, volume_mounts, str) = [path] { + name == volume_mounts[j].name + path := sprintf("%s.volumeMounts[%v]", [str, j]) +} else = [] \ No newline at end of file diff --git a/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/expected.json b/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/expected.json index 98f764d96..4b25ada8c 100644 --- a/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/expected.json +++ b/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/expected.json @@ -1,11 +1,13 @@ [ { "alertMessage": "Deployment: my-deployment has: test-volume as volume with potential credentials access.", - "deletePaths": [ - "spec.template.spec.volumes[0].hostPath.path" - ], "failedPaths": [ - "spec.template.spec.volumes[0].hostPath.path" + "spec.template.spec.volumes[0]", + "spec.template.spec.containers[0].volumeMounts[0]" + ], + "deletePaths": [ + "spec.template.spec.volumes[0]", + "spec.template.spec.containers[0].volumeMounts[0]" ], "fixPaths": [], "ruleStatus": "", @@ -28,11 +30,13 @@ }, { "alertMessage": "Deployment: my-deployment has: test-volume2 as volume with potential credentials access.", - "deletePaths": [ - "spec.template.spec.volumes[1].hostPath.path" - ], "failedPaths": [ - "spec.template.spec.volumes[1].hostPath.path" + "spec.template.spec.volumes[1]", + "spec.template.spec.containers[0].volumeMounts[1]" + ], + "deletePaths": [ + "spec.template.spec.volumes[1]", + "spec.template.spec.containers[0].volumeMounts[1]" ], "fixPaths": [], "ruleStatus": "", diff --git a/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/input/deployment.yaml b/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/input/deployment.yaml index cf95f620b..aa07d6fa6 100644 --- a/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/input/deployment.yaml +++ b/rules/alert-mount-potential-credentials-paths/test/deployment_eks_failed/input/deployment.yaml @@ -23,7 +23,7 @@ spec: name : test-volume - mountPath : /test-pd2 - name : test-volume + name : test-volume2 volumes : - name : test-volume hostPath : diff --git a/rules/alert-mount-potential-credentials-paths/test/pod_eks_failed/expected.json b/rules/alert-mount-potential-credentials-paths/test/pod_eks_failed/expected.json index 4636386ac..00f0f7995 100644 --- a/rules/alert-mount-potential-credentials-paths/test/pod_eks_failed/expected.json +++ b/rules/alert-mount-potential-credentials-paths/test/pod_eks_failed/expected.json @@ -1,24 +1,28 @@ -{ - "alertMessage": "Pod: test-pd has: test-volume as volume with potential credentials access.", - "deletePaths": [ - "spec.volumes[0].hostPath.path" - ], - "failedPaths": [ - "spec.volumes[0].hostPath.path" - ], - "fixPaths": [], - "ruleStatus": "", - "packagename": "armo_builtins", - "alertScore": 7, - "alertObject": { - "k8sApiObjects": [ - { - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "test-pd" +[ + { + "alertMessage": "Pod: test-pd has: test-volume as volume with potential credentials access.", + "failedPaths": [ + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" + ], + "deletePaths": [ + "spec.volumes[0]", + "spec.containers[0].volumeMounts[0]" + ], + "fixPaths": [], + "ruleStatus": "", + "packagename": "armo_builtins", + "alertScore": 7, + "alertObject": { + "k8sApiObjects": [ + { + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "test-pd" + } } - } - ] + ] + } } -} \ No newline at end of file +] \ No newline at end of file diff --git a/rules/alert-rw-hostpath/raw.rego b/rules/alert-rw-hostpath/raw.rego index 96195abb3..d3f989e09 100644 --- a/rules/alert-rw-hostpath/raw.rego +++ b/rules/alert-rw-hostpath/raw.rego @@ -12,9 +12,7 @@ deny[msga] { volume_mount := container.volumeMounts[k] volume_mount.name == volume.name start_of_path := "spec." - result := is_rw_mount(volume_mount, start_of_path, i, k) - failed_path := get_failed_path(result) - fixed_path := get_fixed_path(result) + fix_path := is_rw_mount(volume_mount, start_of_path, i, k) podname := pod.metadata.name @@ -22,9 +20,7 @@ deny[msga] { "alertMessage": sprintf("pod: %v has: %v as hostPath volume", [podname, volume.name]), "packagename": "armo_builtins", "alertScore": 7, - "fixPaths": fixed_path, - "deletePaths": failed_path, - "failedPaths": failed_path, + "fixPaths": [fix_path], "alertObject": { "k8sApiObjects": [pod] } @@ -43,17 +39,13 @@ deny[msga] { volume_mount := container.volumeMounts[k] volume_mount.name == volume.name start_of_path := "spec.template.spec." - result := is_rw_mount(volume_mount, start_of_path, i, k) - failed_path := get_failed_path(result) - fixed_path := get_fixed_path(result) + fix_path := is_rw_mount(volume_mount, start_of_path, i, k) msga := { "alertMessage": sprintf("%v: %v has: %v as hostPath volume", [wl.kind, wl.metadata.name, volume.name]), "packagename": "armo_builtins", "alertScore": 7, - "fixPaths": fixed_path, - "deletePaths": failed_path, - "failedPaths": failed_path, + "fixPaths": [fix_path], "alertObject": { "k8sApiObjects": [wl] } @@ -73,43 +65,22 @@ deny[msga] { volume_mount := container.volumeMounts[k] volume_mount.name == volume.name start_of_path := "spec.jobTemplate.spec.template.spec." - result := is_rw_mount(volume_mount, start_of_path, i, k) - failed_path := get_failed_path(result) - fixed_path := get_fixed_path(result) + fix_path := is_rw_mount(volume_mount, start_of_path, i, k) msga := { "alertMessage": sprintf("%v: %v has: %v as hostPath volume", [wl.kind, wl.metadata.name, volume.name]), "packagename": "armo_builtins", "alertScore": 7, - "fixPaths": fixed_path, - "deletePaths": failed_path, - "failedPaths": failed_path, + "fixPaths": [fix_path], "alertObject": { "k8sApiObjects": [wl] } } } -get_failed_path(paths) = [paths[0]] { - paths[0] != "" -} else = [] - -get_fixed_path(paths) = [paths[1]] { - paths[1] != "" -} else = [] - - -is_rw_mount(mount, start_of_path, i, k) = [failed_path, fix_path] { +is_rw_mount(mount, start_of_path, i, k) = fix_path { not mount.readOnly == true - not mount.readOnly == false - failed_path = "" - fix_path = {"path": sprintf("%vcontainers[%v].volumeMounts[%v].readOnly", [start_of_path, format_int(i, 10), format_int(k, 10)]), "value":"true"} + fix_path = {"path": sprintf("%vcontainers[%v].volumeMounts[%v].readOnly", [start_of_path, i, k]), "value":"true"} } - -is_rw_mount(mount, start_of_path, i, k) = [failed_path, fix_path] { - mount.readOnly == false - failed_path = sprintf("%vcontainers[%v].volumeMounts[%v].readOnly", [start_of_path, format_int(i, 10), format_int(k, 10)]) - fix_path = "" -} \ No newline at end of file diff --git a/rules/alert-rw-hostpath/test/deployment/expected.json b/rules/alert-rw-hostpath/test/deployment/expected.json index 79fdc914c..f142fca21 100644 --- a/rules/alert-rw-hostpath/test/deployment/expected.json +++ b/rules/alert-rw-hostpath/test/deployment/expected.json @@ -1,44 +1,54 @@ -[{ - "alertMessage": "Deployment: my-deployment has: test-volume as hostPath volume", - "deletePaths": ["spec.template.spec.containers[0].volumeMounts[0].readOnly"], - "failedPaths": ["spec.template.spec.containers[0].volumeMounts[0].readOnly"], - "fixPaths": [], - "ruleStatus": "", - "packagename": "armo_builtins", - "alertScore": 7, - "alertObject": { - "k8sApiObjects": [{ - "apiVersion": "apps/v1", - "kind": "Deployment", - "metadata": { - "labels": { - "purpose": "demonstrate-command" - }, - "name": "my-deployment" +[ + { + "alertMessage": "Deployment: my-deployment has: test-volume as hostPath volume", + "fixPaths": [ + { + "path": "spec.template.spec.containers[0].volumeMounts[0].readOnly", + "value": "true" } - }] - } -}, { - "alertMessage": "Deployment: my-deployment has: test-volume as hostPath volume", - "deletePaths": [], - "failedPaths": [], - "fixPaths": [{ - "path": "spec.template.spec.containers[0].volumeMounts[1].readOnly", - "value": "true" - }], - "ruleStatus": "", - "packagename": "armo_builtins", - "alertScore": 7, - "alertObject": { - "k8sApiObjects": [{ - "apiVersion": "apps/v1", - "kind": "Deployment", - "metadata": { - "labels": { - "purpose": "demonstrate-command" - }, - "name": "my-deployment" + ], + "ruleStatus": "", + "packagename": "armo_builtins", + "alertScore": 7, + "alertObject": { + "k8sApiObjects": [ + { + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "labels": { + "purpose": "demonstrate-command" + }, + "name": "my-deployment" + } + } + ] + } + }, + { + "alertMessage": "Deployment: my-deployment has: test-volume as hostPath volume", + "fixPaths": [ + { + "path": "spec.template.spec.containers[0].volumeMounts[1].readOnly", + "value": "true" } - }] + ], + "ruleStatus": "", + "packagename": "armo_builtins", + "alertScore": 7, + "alertObject": { + "k8sApiObjects": [ + { + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "labels": { + "purpose": "demonstrate-command" + }, + "name": "my-deployment" + } + } + ] + } } -}] \ No newline at end of file +] \ No newline at end of file