Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(query): Extend net_raw_capabilities_not_being_dropped k8s rule to cover further resource kinds #4884

Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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"])
}
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]