Skip to content

Commit

Permalink
Merge branch 'master' of github.com:kubescape/regolibrary into SUB-21…
Browse files Browse the repository at this point in the history
…85-fix-control-C-0262

Signed-off-by: YiscahLevySilas1 <[email protected]>
  • Loading branch information
YiscahLevySilas1 committed Oct 9, 2023
2 parents 423f6d7 + f1cf9c1 commit 3d1d699
Show file tree
Hide file tree
Showing 38 changed files with 298 additions and 237 deletions.
2 changes: 1 addition & 1 deletion ControlID_RuleName.csv
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ C-0073,naked-pods
C-0074,containers-mounting-docker-socket
C-0075,image-pull-policy-is-not-set-to-always
C-0076,label-usage-for-resources
C-0077,K8s common labels usage
C-0077,k8s-common-labels-usage
C-0078,container-image-repository
C-0079,CVE-2022-0185
C-0081,CVE-2022-24348
Expand Down
2 changes: 1 addition & 1 deletion controls/C-0077-k8scommonlabelsusage.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"description": "Kubernetes common labels help manage and monitor Kubernetes cluster using different tools such as kubectl, dashboard and others in an interoperable way. Refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ for more information. This control helps you find objects that don't have any of these labels defined.",
"remediation": "Define applicable labels or use the exception mechanism to prevent further notifications.",
"rulesNames": [
"K8s common labels usage"
"k8s-common-labels-usage"
],
"long_description": "Kubernetes common labels help manage and monitor Kubernetes cluster using different tools such as kubectl, dashboard and others in an interoperable way. Refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ for more information. This control helps you find objects that don't have any of these labels defined.",
"test": "Test will check if the list of label that start with app.kubernetes.io/ are defined.",
Expand Down
16 changes: 8 additions & 8 deletions rules/CVE-2021-25741/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ deny[msga] {
pod := input[_]
pod.kind == "Pod"
container := pod.spec.containers[i]
beggining_of_path := "spec."
final_path := is_sub_path_container(container, i, beggining_of_path)
start_of_path := "spec."
final_path := is_sub_path_container(container, i, start_of_path)

msga := {
"alertMessage": sprintf("You may be vulnerable to CVE-2021-25741. You have a Node with a vulnerable version and the following container : %v in pod : %v with subPath/subPathExpr", [container.name, pod.metadata.name]),
Expand All @@ -29,8 +29,8 @@ deny[msga] {
spec_template_spec_patterns := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
spec_template_spec_patterns[wl.kind]
container := wl.spec.template.spec.containers[i]
beggining_of_path := "spec.template.spec."
final_path := is_sub_path_container(container, i, beggining_of_path)
start_of_path := "spec.template.spec."
final_path := is_sub_path_container(container, i, start_of_path)

msga := {
"alertMessage": sprintf("You may be vulnerable to CVE-2021-25741. You have a Node with a vulnerable version and the following container : %v in %v : %v with subPath/subPathExpr", [container.name, wl.kind, wl.metadata.name]),
Expand All @@ -50,8 +50,8 @@ deny[msga] {
wl := input[_]
wl.kind == "CronJob"
container = wl.spec.jobTemplate.spec.template.spec.containers[i]
beggining_of_path := "spec.jobTemplate.spec.template.spec."
final_path := is_sub_path_container(container, i, beggining_of_path)
start_of_path := "spec.jobTemplate.spec.template.spec."
final_path := is_sub_path_container(container, i, start_of_path)

msga := {
"alertMessage": sprintf("You may be vulnerable to CVE-2021-25741. You have a Node with a vulnerable version and the following container : %v in %v : %v with subPath/subPathExpr", [container.name, wl.kind, wl.metadata.name]),
Expand All @@ -64,8 +64,8 @@ deny[msga] {



is_sub_path_container(container, i, beggining_of_path) = path {
path = [sprintf("%vcontainers[%v].volumeMounts[%v].subPath" ,[beggining_of_path, format_int(i, 10), format_int(j, 10)]) | volume_mount = container.volumeMounts[j]; volume_mount.subPath]
is_sub_path_container(container, i, start_of_path) = path {
path = [sprintf("%vcontainers[%v].volumeMounts[%v].subPath" ,[start_of_path, format_int(i, 10), format_int(j, 10)]) | volume_mount = container.volumeMounts[j]; volume_mount.subPath]
count(path) > 0
}

Expand Down
90 changes: 45 additions & 45 deletions rules/CVE-2022-0492/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ deny[msga] {
container := pod.spec.containers[i]

# Path to send
beggining_of_path := "spec"
start_of_path := "spec"

# If container is privileged or has CAP_SYS_ADMIN, pass
not container.securityContext.privileged == true
not is_cap_sys_admin(container, beggining_of_path)
not is_cap_sys_admin(container, start_of_path)


is_no_SELinux_No_AppArmor_Pod(pod)
Expand All @@ -28,10 +28,10 @@ deny[msga] {
is_no_Seccomp_Container(container)

# Check if is running as root
alertInfo := evaluate_workload_non_root_container(container, pod, beggining_of_path)
alertInfo := evaluate_workload_non_root_container(container, pod, start_of_path)

# CAP_DAC_OVERRIDE will fail on second check
not isCAP_DAC_OVERRIDE(container, beggining_of_path, i)
not isCAP_DAC_OVERRIDE(container, start_of_path, i)

# Get paths
fixPath := get_fixed_path(alertInfo, i)
Expand All @@ -55,14 +55,14 @@ deny[msga] {
wl := input[_]
spec_template_spec_patterns := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
spec_template_spec_patterns[wl.kind]
beggining_of_path := "spec.template.spec"
start_of_path := "spec.template.spec"

pod := wl.spec.template
container := pod.spec.containers[i]

# If container is privileged or has CAP_SYS_ADMIN, pass
not container.securityContext.privileged == true
not is_cap_sys_admin(container, beggining_of_path)
not is_cap_sys_admin(container, start_of_path)


is_no_SELinux_No_AppArmor_Pod(pod)
Expand All @@ -72,10 +72,10 @@ deny[msga] {
is_no_Seccomp_Container(container)

# Check if is running as root
alertInfo := evaluate_workload_non_root_container(container, pod, beggining_of_path)
alertInfo := evaluate_workload_non_root_container(container, pod, start_of_path)

# CAP_DAC_OVERRIDE will fail on second check
not isCAP_DAC_OVERRIDE(container, beggining_of_path, i)
not isCAP_DAC_OVERRIDE(container, start_of_path, i)

# Get paths
fixPath := get_fixed_path(alertInfo, i)
Expand All @@ -98,14 +98,14 @@ deny[msga] {
deny[msga] {
wl := input[_]
wl.kind == "CronJob"
beggining_of_path := "spec.jobTemplate.spec.template.spec"
start_of_path := "spec.jobTemplate.spec.template.spec"

pod := wl.spec.jobTemplate.spec.template
container = pod.spec.containers[i]

# If container is privileged or has CAP_SYS_ADMIN, pass
not container.securityContext.privileged == true
not is_cap_sys_admin(container, beggining_of_path)
not is_cap_sys_admin(container, start_of_path)


is_no_SELinux_No_AppArmor_Pod(pod)
Expand All @@ -115,10 +115,10 @@ deny[msga] {
is_no_Seccomp_Container(container)

# Check if is running as root
alertInfo := evaluate_workload_non_root_container(container, pod, beggining_of_path)
alertInfo := evaluate_workload_non_root_container(container, pod, start_of_path)

# CAP_DAC_OVERRIDE will fail on second check
not isCAP_DAC_OVERRIDE(container, beggining_of_path, i)
not isCAP_DAC_OVERRIDE(container, start_of_path, i)

# Get paths
fixPath := get_fixed_path(alertInfo, i)
Expand Down Expand Up @@ -150,13 +150,13 @@ deny[msga] {
pod.kind == "Pod"
container := pod.spec.containers[i]

beggining_of_path := "spec."
start_of_path := "spec."

result := isCAP_DAC_OVERRIDE(container, beggining_of_path, i)
result := isCAP_DAC_OVERRIDE(container, start_of_path, i)

# If container is privileged or has CAP_SYS_ADMIN, pass
not container.securityContext.privileged == true
not is_cap_sys_admin(container, beggining_of_path)
not is_cap_sys_admin(container, start_of_path)

is_no_SELinux_No_AppArmor_Pod(pod)
is_no_SELinux_container(container)
Expand All @@ -182,13 +182,13 @@ deny[msga] {
pod := wl.spec.template
container := pod.spec.containers[i]

beggining_of_path := "spec.template.spec."
start_of_path := "spec.template.spec."

result := isCAP_DAC_OVERRIDE(container, beggining_of_path, i)
result := isCAP_DAC_OVERRIDE(container, start_of_path, i)

# If container is privileged or has CAP_SYS_ADMIN, pass
not container.securityContext.privileged == true
not is_cap_sys_admin(container, beggining_of_path)
not is_cap_sys_admin(container, start_of_path)

is_no_SELinux_No_AppArmor_Pod(pod)
is_no_SELinux_container(container)
Expand All @@ -213,13 +213,13 @@ deny[msga] {
pod := wl.spec.jobTemplate.spec.template
container = pod.spec.containers[i]

beggining_of_path := "spec.jobTemplate.spec.template.spec."
start_of_path := "spec.jobTemplate.spec.template.spec."

result := isCAP_DAC_OVERRIDE(container, beggining_of_path, i)
result := isCAP_DAC_OVERRIDE(container, start_of_path, i)

# If container is privileged or has CAP_SYS_ADMIN, pass
not container.securityContext.privileged == true
not is_cap_sys_admin(container, beggining_of_path)
not is_cap_sys_admin(container, start_of_path)

is_no_SELinux_No_AppArmor_Pod(pod)
is_no_SELinux_container(container)
Expand All @@ -240,15 +240,15 @@ deny[msga] {



is_cap_sys_admin(container, beggining_of_path) {
is_cap_sys_admin(container, start_of_path) {
capability = container.securityContext.capabilities.add[k]
capability == "SYS_ADMIN"
}

isCAP_DAC_OVERRIDE(container, beggining_of_path, i) = path {
isCAP_DAC_OVERRIDE(container, start_of_path, i) = path {
capability = container.securityContext.capabilities.add[k]
capability == "DAC_OVERRIDE"
path = sprintf("%vcontainers[%v].securityContext.capabilities.add[%v]", [beggining_of_path, format_int(i, 10), format_int(k, 10)])
path = sprintf("%vcontainers[%v].securityContext.capabilities.add[%v]", [start_of_path, format_int(i, 10), format_int(k, 10)])
}


Expand Down Expand Up @@ -300,16 +300,16 @@ is_no_Seccomp_Container(container) {
#################################################################################
# Workload evaluation

evaluate_workload_non_root_container(container, pod, beggining_of_path) = alertInfo {
runAsNonRootValue := get_run_as_non_root_value(container, pod, beggining_of_path)
evaluate_workload_non_root_container(container, pod, start_of_path) = alertInfo {
runAsNonRootValue := get_run_as_non_root_value(container, pod, start_of_path)
runAsNonRootValue.value == false

runAsUserValue := get_run_as_user_value(container, pod, beggining_of_path)
runAsUserValue := get_run_as_user_value(container, pod, start_of_path)
runAsUserValue.value == 0

alertInfo := choose_first_if_defined(runAsUserValue, runAsNonRootValue)
} else = alertInfo {
allowPrivilegeEscalationValue := get_allow_privilege_escalation(container, pod, beggining_of_path)
allowPrivilegeEscalationValue := get_allow_privilege_escalation(container, pod, start_of_path)
allowPrivilegeEscalationValue.value == true

alertInfo := allowPrivilegeEscalationValue
Expand All @@ -319,48 +319,48 @@ evaluate_workload_non_root_container(container, pod, beggining_of_path) = alertI
#################################################################################

# Checking for non-root and allowPrivilegeEscalation enabled
get_run_as_non_root_value(container, pod, beggining_of_path) = runAsNonRoot {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [beggining_of_path])
get_run_as_non_root_value(container, pod, start_of_path) = runAsNonRoot {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [start_of_path])
runAsNonRoot := {"value" : container.securityContext.runAsNonRoot, "failed_path" : failed_path, "fixPath": [] ,"defined" : true}
} else = runAsNonRoot {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [beggining_of_path])
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [start_of_path])
runAsNonRoot := {"value" : pod.spec.securityContext.runAsNonRoot, "failed_path" : failed_path, "fixPath": [], "defined" : true}
} else = {"value" : false, "failed_path" : "", "fixPath": [{"path": "spec.securityContext.runAsNonRoot", "value":"true"}], "defined" : false} {
is_allow_privilege_escalation_field(container, pod)
} else = {"value" : false, "failed_path" : "", "fixPath": [{"path": sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [beggining_of_path]) , "value":"true"}, {"path":sprintf("%v.containers[container_ndx].securityContext.allowPrivilegeEscalation", [beggining_of_path]), "value":"false"}], "defined" : false}
} else = {"value" : false, "failed_path" : "", "fixPath": [{"path": sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [start_of_path]) , "value":"true"}, {"path":sprintf("%v.containers[container_ndx].securityContext.allowPrivilegeEscalation", [start_of_path]), "value":"false"}], "defined" : false}

get_run_as_user_value(container, pod, beggining_of_path) = runAsUser {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsUser", [beggining_of_path])
get_run_as_user_value(container, pod, start_of_path) = runAsUser {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsUser", [start_of_path])
runAsUser := {"value" : container.securityContext.runAsUser, "failed_path" : failed_path, "fixPath": [], "defined" : true}
} else = runAsUser {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsUser", [beggining_of_path])
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsUser", [start_of_path])
runAsUser := {"value" : pod.spec.securityContext.runAsUser, "failed_path" : failed_path, "fixPath": [],"defined" : true}
} else = {"value" : 0, "failed_path": "", "fixPath": [{"path": sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [beggining_of_path]), "value":"true"}],"defined" : false}{
} else = {"value" : 0, "failed_path": "", "fixPath": [{"path": sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [start_of_path]), "value":"true"}],"defined" : false}{
is_allow_privilege_escalation_field(container, pod)
} else = {"value" : 0, "failed_path": "",
"fixPath": [{"path": sprintf("%v.securityContext.containers[container_ndx].runAsNonRoot", [beggining_of_path]), "value":"true"},{"path": sprintf("%v.containers[container_ndx].securityContext.allowPrivilegeEscalation", [beggining_of_path]), "value":"false"}],
"fixPath": [{"path": sprintf("%v.securityContext.containers[container_ndx].runAsNonRoot", [start_of_path]), "value":"true"},{"path": sprintf("%v.containers[container_ndx].securityContext.allowPrivilegeEscalation", [start_of_path]), "value":"false"}],
"defined" : false}

get_run_as_group_value(container, pod, beggining_of_path) = runAsGroup {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsGroup", [beggining_of_path])
get_run_as_group_value(container, pod, start_of_path) = runAsGroup {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsGroup", [start_of_path])
runAsGroup := {"value" : container.securityContext.runAsGroup, "failed_path" : failed_path, "fixPath": [],"defined" : true}
} else = runAsGroup {
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsGroup", [beggining_of_path])
failed_path := sprintf("%v.containers[container_ndx].securityContext.runAsGroup", [start_of_path])
runAsGroup := {"value" : pod.spec.securityContext.runAsGroup, "failed_path" : failed_path, "fixPath":[], "defined" : true}
} else = {"value" : 0, "failed_path": "", "fixPath": [{"path": "spec.securityContext.runAsNonRoot", "value":"true"}], "defined" : false}{
is_allow_privilege_escalation_field(container, pod)
} else = {"value" : 0, "failed_path": "",
"fixPath": [{"path": sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [beggining_of_path]), "value":"true"},{"path": sprintf("%v.securityContext.allowPrivilegeEscalation", [beggining_of_path]), "value":"false"}],
"fixPath": [{"path": sprintf("%v.containers[container_ndx].securityContext.runAsNonRoot", [start_of_path]), "value":"true"},{"path": sprintf("%v.securityContext.allowPrivilegeEscalation", [start_of_path]), "value":"false"}],
"defined" : false
}

get_allow_privilege_escalation(container, pod, beggining_of_path) = allowPrivilegeEscalation {
failed_path := sprintf("%v.containers[container_ndx].securityContext.allowPrivilegeEscalation", [beggining_of_path])
get_allow_privilege_escalation(container, pod, start_of_path) = allowPrivilegeEscalation {
failed_path := sprintf("%v.containers[container_ndx].securityContext.allowPrivilegeEscalation", [start_of_path])
allowPrivilegeEscalation := {"value" : container.securityContext.allowPrivilegeEscalation, "failed_path" : failed_path, "fixPath": [],"defined" : true}
} else = allowPrivilegeEscalation {
failed_path := sprintf("%v.securityContext.allowPrivilegeEscalation", [beggining_of_path])
failed_path := sprintf("%v.securityContext.allowPrivilegeEscalation", [start_of_path])
allowPrivilegeEscalation := {"value" : pod.spec.securityContext.allowPrivilegeEscalation, "failed_path" : failed_path, "fixPath": [],"defined" : true}
} else = {"value" : true, "failed_path": "", "fixPath": [{"path": sprintf("%v.securityContext.allowPrivilegeEscalation", [beggining_of_path]), "value":"false"}], "defined" : false}
} else = {"value" : true, "failed_path": "", "fixPath": [{"path": sprintf("%v.securityContext.allowPrivilegeEscalation", [start_of_path]), "value":"false"}], "defined" : false}

choose_first_if_defined(l1, l2) = c {
l1.defined
Expand Down
16 changes: 8 additions & 8 deletions rules/alert-any-hostpath/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ deny[msga] {
pod.kind == "Pod"
volumes := pod.spec.volumes
volume := volumes[i]
beggining_of_path := "spec."
result := is_dangerous_volume(volume, beggining_of_path, i)
start_of_path := "spec."
result := is_dangerous_volume(volume, start_of_path, i)
podname := pod.metadata.name


Expand All @@ -31,8 +31,8 @@ deny[msga] {
spec_template_spec_patterns[wl.kind]
volumes := wl.spec.template.spec.volumes
volume := volumes[i]
beggining_of_path := "spec.template.spec."
result := is_dangerous_volume(volume, beggining_of_path, i)
start_of_path := "spec.template.spec."
result := is_dangerous_volume(volume, start_of_path, i)


msga := {
Expand All @@ -54,8 +54,8 @@ deny[msga] {
wl.kind == "CronJob"
volumes := wl.spec.jobTemplate.spec.template.spec.volumes
volume := volumes[i]
beggining_of_path := "spec.jobTemplate.spec.template.spec."
result := is_dangerous_volume(volume, beggining_of_path, i)
start_of_path := "spec.jobTemplate.spec.template.spec."
result := is_dangerous_volume(volume, start_of_path, i)
msga := {
"alertMessage": sprintf("%v: %v has: %v as hostPath volume", [wl.kind, wl.metadata.name, volume.name]),
"packagename": "armo_builtins",
Expand All @@ -69,7 +69,7 @@ deny[msga] {
}
}

is_dangerous_volume(volume, beggining_of_path, i) = path {
is_dangerous_volume(volume, start_of_path, i) = path {
volume.hostPath.path
path = sprintf("%vvolumes[%v].hostPath.path", [beggining_of_path, format_int(i, 10)])
path = sprintf("%vvolumes[%v].hostPath.path", [start_of_path, format_int(i, 10)])
}
Loading

0 comments on commit 3d1d699

Please sign in to comment.