diff --git a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/metadata.json b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/metadata.json index a957799d6d0..5544f2ef2fa 100644 --- a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/metadata.json +++ b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/metadata.json @@ -3,7 +3,7 @@ "queryName": "NET_RAW Capabilities Not Being Dropped", "severity": "HIGH", "category": "Insecure Configurations", - "descriptionText": "Containers should drop 'NET_RAW' or 'ALL' capabilities", + "descriptionText": "Containers should drop 'ALL' or at least 'NET_RAW' capabilities", "descriptionUrl": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", "platform": "Kubernetes", "descriptionID": "e9790956" diff --git a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/query.rego b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/query.rego index a7e24fc8ea4..b0676c2f14f 100644 --- a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/query.rego +++ b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/query.rego @@ -1,77 +1,46 @@ package Cx import data.generic.common as common_lib +import data.generic.k8s as k8sLib types := {"initContainers", "containers"} CxPolicy[result] { document := input.document[i] - document.kind == "Pod" metadata := document.metadata - spec := document.spec - containers := spec[types[x]] - capabilities := spec.containers[k].securityContext.capabilities - not common_lib.compareArrays(capabilities.drop, ["ALL", "NET_RAW"]) - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities.drop", [metadata.name, types[x], containers[k].name]), - "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities.drop is ALL or NET_RAW", [metadata.name, types[x], containers[k].name]), - "keyActualValue": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities.drop is not ALL or NET_RAW", [metadata.name, types[x], containers[k].name]), - } -} + specInfo = k8sLib.getSpecInfo(document) + container := specInfo.spec[types[x]][_] -CxPolicy[result] { - document := input.document[i] - document.kind == "Pod" - metadata := document.metadata - spec := document.spec - containers := spec[types[x]] - - not common_lib.valid_key(spec.containers[k].securityContext.capabilities, "drop") + capabilities := container.securityContext.capabilities + not common_lib.compareArrays(capabilities.drop, ["ALL", "NET_RAW"]) result := { - "documentId": input.document[i].id, - "searchKey": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities", [metadata.name, types[x], containers[k].name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities.drop is set", [metadata.name, types[x], containers[k].name]), - "keyActualValue": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities.drop is undefined", [metadata.name, types[x], containers[k].name]), + "documentId": document.id, + "searchKey": sprintf("metadata.name={{%s}}.%s.%s.name={{%s}}.securityContext.capabilities.drop", [metadata.name, specInfo.path, types[x], container.name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("metadata.name={{%s}}.%s.%s.name={{%s}}.securityContext.capabilities.drop includes ALL or NET_RAW", [metadata.name, specInfo.path, types[x], container.name]), + "keyActualValue": sprintf("metadata.name={{%s}}.%s.%s.name={{%s}}.securityContext.capabilities.drop does not include ALL or NET_RAW", [metadata.name, specInfo.path, types[x], container.name]), } } CxPolicy[result] { document := input.document[i] - document.kind == "Pod" metadata := document.metadata - spec := document.spec - containers := spec[types[x]] - - not common_lib.valid_key(spec.containers[k].securityContext, "capabilities") - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext", [metadata.name, types[x], containers[k].name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities is set", [metadata.name, types[x], containers[k].name]), - "keyActualValue": sprintf("metadata.name={{%s}}.spec.%s.name={{%s}}.securityContext.capabilities is undefined", [metadata.name, types[x], containers[k].name]), - } -} -CxPolicy[result] { - document := input.document[i] - document.kind == "Pod" - metadata := document.metadata - spec := document.spec - containers := spec[types[x]] + specInfo = k8sLib.getSpecInfo(document) + container := specInfo.spec[types[x]][c] - not common_lib.valid_key(spec.containers[k], "securityContext") + containerCtx := object.get(container, "securityContext", {}) + containerCapabilitiesCtx := object.get(containerCtx, "capabilities", {}) + not common_lib.valid_key(containerCapabilitiesCtx, "drop") result := { - "documentId": input.document[i].id, - "searchKey": sprintf("metadata.name={{%s}}.spec.%s.name=%s", [metadata.name, types[x], containers[k].name]), + "documentId": document.id, + "searchKey": sprintf("metadata.name={{%s}}.%s.%s.name={{%s}}", [metadata.name, specInfo.path, types[x], container.name]), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("metadata.name={{%s}}.spec.%s.name=%s.securityContext is set", [metadata.name, types[x], containers[k].name]), - "keyActualValue": sprintf("metadata.name={{%s}}.spec.%s.name=%s.securityContext is undefined", [metadata.name, types[x], containers[k].name]), + "keyExpectedValue": sprintf("metadata.name={{%s}}.%s.%s.name={{%s}}.securityContext.capabilities.drop should be defined", [metadata.name, specInfo.path, types[x], container.name]), + "keyActualValue": sprintf("metadata.name={{%s}}.%s.%s.name={{%s}}.securityContext.capabilities.drop is undefined", [metadata.name, specInfo.path, types[x], container.name]), + "searchLine": common_lib.build_search_line(split(specInfo.path, "."), [types[x], c, "securityContext", "capabilities"]) } } diff --git a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive.yaml b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive1.yaml similarity index 100% rename from assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive.yaml rename to assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive1.yaml diff --git a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive2.yaml b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive2.yaml new file mode 100644 index 00000000000..1e779339b05 --- /dev/null +++ b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive2.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis-unhealthy-deployment + labels: + app: redis +spec: + replicas: 3 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + hostNetwork: true + hostPID: true + hostIPC: true + containers: + - name: redis + image: redis:latest + ports: + - containerPort: 9001 + hostPort: 9001 + securityContext: + privileged: true + readOnlyRootFilesystem: false + allowPrivilegeEscalation: true + runAsUser: 0 + capabilities: + add: + - NET_ADMIN \ No newline at end of file diff --git a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive_expected_result.json b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive_expected_result.json index 7db440741d2..e8c992007bd 100644 --- a/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive_expected_result.json +++ b/assets/queries/k8s/net_raw_capabilities_not_being_dropped/test/positive_expected_result.json @@ -2,21 +2,31 @@ { "queryName": "NET_RAW Capabilities Not Being Dropped", "severity": "HIGH", - "line": 11 + "line": 11, + "fileName": "positive1.yaml" }, { "queryName": "NET_RAW Capabilities Not Being Dropped", "severity": "HIGH", - "line": 18 + "line": 18, + "fileName": "positive1.yaml" }, { "queryName": "NET_RAW Capabilities Not Being Dropped", "severity": "HIGH", - "line": 23 + "line": 21, + "fileName": "positive1.yaml" }, { "queryName": "NET_RAW Capabilities Not Being Dropped", "severity": "HIGH", - "line": 13 + "line": 13, + "fileName": "positive1.yaml" + }, + { + "queryName": "NET_RAW Capabilities Not Being Dropped", + "severity": "HIGH", + "line": 31, + "fileName": "positive2.yaml" } ]