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 M-112 and use CEL optional values and variables in built-in checks #39

Merged
merged 4 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions internal/builtins/cis/M-500_default_namespace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,4 @@ match:
version: v1
resource: jobs
validations:
- expression: >
has(object.metadata.namespace)
&& (type(object.metadata.namespace) == string)
&& !(object.metadata.namespace == 'default')
- expression: object.metadata.?namespace.orValue("default") != "default"
8 changes: 4 additions & 4 deletions internal/builtins/general/M-401_unmanaged_pod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ match:
- group: ""
version: v1
resource: pods
variables:
- name: owners
expression: object.metadata.?ownerReferences.orValue([])
validations:
- expression: >
has(object.metadata.ownerReferences) &&
object.metadata.ownerReferences != null &&
object.metadata.ownerReferences.size() > 0 &&
object.metadata.ownerReferences.exists(o, has(o.controller) && o.controller == true)
variables.owners != null && variables.owners.exists(o, o.?controller.orValue(false) == true)
11 changes: 6 additions & 5 deletions internal/builtins/general/M-402_readiness_probe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ match:
- group: apps
version: v1
resource: replicasets
variables:
- name: owners
expression: object.metadata.?ownerReferences.orValue([])
validations:
- expression: >
(
object.kind == "Pod" &&
has(object.metadata.ownerReferences) &&
object.metadata.ownerReferences != null &&
object.metadata.ownerReferences.size() > 0 &&
object.metadata.ownerReferences.exists(o, has(o.kind) && has(o.apiVersion) && o.kind == "Job" && o.apiVersion == "batch/v1")
variables.owners != null &&
variables.owners.exists(o, o.?kind.orValue("") == "Job" && o.?apiVersion.orValue("") == "batch/v1")
)
||
podSpec.containers.all(container, has(container.readinessProbe) || has(container.startupProbe))
podSpec.containers.all(c, has(c.readinessProbe) || has(c.startupProbe))
9 changes: 6 additions & 3 deletions internal/builtins/general/M-403_liveness_probe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ match:
- group: apps
version: v1
resource: replicasets
variables:
- name: owners
expression: object.metadata.?ownerReferences.orValue([])
validations:
- expression: >
(
object.kind == "Pod" &&
has(object.metadata.ownerReferences) &&
object.metadata.ownerReferences.exists(o, has(o.kind) && has(o.apiVersion) && o.kind == "Job" && o.apiVersion == "batch/v1")
variables.owners != null &&
variables.owners.exists(o, o.?kind.orValue("") == "Job" && o.?apiVersion.orValue("") == "batch/v1")
)
||
podSpec.containers.all(container, has(container.livenessProbe))
podSpec.containers.all(c, has(c.livenessProbe))
6 changes: 1 addition & 5 deletions internal/builtins/general/M-404_memory_requests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,4 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
has(container.resources) &&
has(container.resources.requests) &&
has(container.resources.requests.memory)
)
allContainers.all(c, c.?resources.?requests.?memory.orValue("") != "")
6 changes: 1 addition & 5 deletions internal/builtins/general/M-405_cpu_requests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,4 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
has(container.resources) &&
has(container.resources.requests) &&
has(container.resources.requests.cpu)
)
allContainers.all(c, c.?resources.?requests.?cpu.orValue("") != "")
6 changes: 1 addition & 5 deletions internal/builtins/general/M-406_memory_limit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,4 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
has(container.resources) &&
has(container.resources.limits) &&
has(container.resources.limits.memory)
)
allContainers.all(c, c.?resources.?limits.?memory.orValue("") != "")
6 changes: 1 addition & 5 deletions internal/builtins/general/M-407_cpu_limit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,4 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
has(container.resources) &&
has(container.resources.limits) &&
has(container.resources.limits.cpu)
)
allContainers.all(c, c.?resources.?limits.?cpu.orValue("") != "")
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
!has(container.command) ||
size(container.command) == 0 ||
container.command.all(cmd,
!cmd.contains("sudo"))
)
allContainers.all(c,
c.?command.orValue([]).all(cmd, !cmd.contains("sudo"))
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,4 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
!container.image.contains("k8s.grc.io"))
allContainers.all(c, !c.image.contains("k8s.grc.io"))
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,4 @@ match:
resource: replicasets
validations:
- expression: >
!has(podSpec.restartPolicy) ||
has(podSpec.restartPolicy) &&
(podSpec.restartPolicy =='Always')
podSpec.?restartPolicy.orValue("Always") == 'Always'
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ match:
resource: jobs
validations:
- expression: >
has(podSpec.automountServiceAccountToken) && podSpec.automountServiceAccountToken == false
podSpec.?automountServiceAccountToken.orValue(true) == false
message: "Pod with Service Account token mounted automatically"
2 changes: 1 addition & 1 deletion internal/builtins/mitre/M-203_ssh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ validations:
!has(object.spec.ports) ||
object.spec.ports.all(p,
!(p.port in params.sshPorts) &&
(!has(p.targetPort) || !(p.targetPort in params.sshPorts))
!(p.?targetPort.orValue(0) in params.sshPorts)
)
message: "Service could be routing to SSH server"
Expand Down
6 changes: 1 addition & 5 deletions internal/builtins/nsa/M-300_read_only_root_filesystem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,5 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
has(container.securityContext) &&
has(container.securityContext.readOnlyRootFilesystem) &&
container.securityContext.readOnlyRootFilesystem == true
)
allContainers.all(c, c.?securityContext.?readOnlyRootFilesystem.orValue(false) == true)
message: "Container is able to write to the root filesystem"
11 changes: 2 additions & 9 deletions internal/builtins/pss/baseline/M-100_host_process.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,8 @@ match:
resource: jobs
validations:
- expression: >
!has(podSpec.securityContext) ||
!has(podSpec.securityContext.windowsOptions) ||
!has(podSpec.securityContext.windowsOptions.hostProcess) ||
podSpec.securityContext.windowsOptions.hostProcess == false
podSpec.?securityContext.?windowsOptions.?hostProcess.orValue(false) == false
message: "Pod with privileged access to the Windows node"
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.windowsOptions) ||
!has(container.securityContext.windowsOptions.hostProcess) ||
container.securityContext.windowsOptions.hostProcess == false)
allContainers.all(c, c.?securityContext.?windowsOptions.?hostProcess.orValue(false) == false)
message: "Container with privileged access to the Windows node"
6 changes: 3 additions & 3 deletions internal/builtins/pss/baseline/M-101_host_namespaces.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ match:
resource: jobs
validations:
- expression: >
(!has(podSpec.hostNetwork) || podSpec.hostNetwork == false) &&
(!has(podSpec.hostPID) || podSpec.hostPID == false) &&
(!has(podSpec.hostIPC) || podSpec.hostIPC == false)
podSpec.?hostNetwork.orValue(false) == false &&
podSpec.?hostPID.orValue(false) == false &&
podSpec.?hostIPC.orValue(false) == false
message: "Pod sharing host namespace"
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,5 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.privileged) ||
container.securityContext.privileged == false)
allContainers.all(c, c.?securityContext.?privileged.orValue(false) == false)
message: "Container running in privileged mode"
7 changes: 1 addition & 6 deletions internal/builtins/pss/baseline/M-103_capabilities.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,5 @@ params:
- SYS_CHROOT
validations:
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.capabilities) ||
!has(container.securityContext.capabilities.add) ||
container.securityContext.capabilities.add.all(cap, cap in params.allowedCapabilities)
)
allContainers.all(c, c.?securityContext.?capabilities.?add.orValue([]).all(cap, cap in params.allowedCapabilities))
message: "Container running with not allowed capabilities"
2 changes: 1 addition & 1 deletion internal/builtins/pss/baseline/M-104_host_path_volumes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ match:
resource: jobs
validations:
- expression: >
!has(podSpec.volumes) || podSpec.volumes.all(vol, !has(vol.hostPath))
podSpec.?volumes.orValue([]).all(v, !has(v.hostPath))
message: "Pod with mounted host volume"
11 changes: 2 additions & 9 deletions internal/builtins/pss/baseline/M-105_host_ports.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,8 @@ match:
version: v1
resource: jobs
params:
allowedHostPorts: []
allowedHostPorts: [0]
validations:
- expression: >
allContainers.all(container,
!has(container.ports) ||
container.ports.all(port,
!has(port.hostPort) ||
port.hostPort == 0 ||
port.hostPort in params.allowedHostPorts
)
)
allContainers.all(c, c.?ports.orValue([]).all(p, p.?hostPort.orValue(0) in params.allowedHostPorts))
message: "Container exposing not allowed port on the host"
39 changes: 7 additions & 32 deletions internal/builtins/pss/baseline/M-107_selinux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,48 +47,23 @@ params:
- container_t
- container_init_t
- container_kvm_t
- ""
validations:
- expression: >
!has(podSpec.securityContext) ||
!has(podSpec.securityContext.seLinuxOptions) ||
!has(podSpec.securityContext.seLinuxOptions.type) ||
podSpec.securityContext.seLinuxOptions.type == '' ||
podSpec.securityContext.seLinuxOptions.type in params.allowedSELinuxTypes
podSpec.?securityContext.?seLinuxOptions.?type.orValue("") in params.allowedSELinuxTypes
message: "Pod with not allowed SELinux type"
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.seLinuxOptions) ||
!has(container.securityContext.seLinuxOptions.type) ||
container.securityContext.seLinuxOptions.type == '' ||
container.securityContext.seLinuxOptions.type in params.allowedSELinuxTypes
)
allContainers.all(c, c.?securityContext.?seLinuxOptions.?type.orValue("") in params.allowedSELinuxTypes)
message: "Container with not allowed SELinux type"
- expression: >
!has(podSpec.securityContext) ||
!has(podSpec.securityContext.seLinuxOptions) ||
!has(podSpec.securityContext.seLinuxOptions.user) ||
podSpec.securityContext.seLinuxOptions.user == ''
podSpec.?securityContext.?seLinuxOptions.?user.orValue("") == ""
message: "Pod with forbidden SELinux user"
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.seLinuxOptions) ||
!has(container.securityContext.seLinuxOptions.user) ||
container.securityContext.seLinuxOptions.user == ''
)
allContainers.all(c, c.?securityContext.?seLinuxOptions.?user.orValue("") == "")
message: "Container with forbidden SELinux user"
- expression: >
!has(podSpec.securityContext) ||
!has(podSpec.securityContext.seLinuxOptions) ||
!has(podSpec.securityContext.seLinuxOptions.role) ||
podSpec.securityContext.seLinuxOptions.role == ''
podSpec.?securityContext.?seLinuxOptions.?role.orValue("") == ""
message: "Pod with forbidden SELinux role"
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.seLinuxOptions) ||
!has(container.securityContext.seLinuxOptions.role) ||
container.securityContext.seLinuxOptions.role == ''
)
allContainers.all(c, c.?securityContext.?seLinuxOptions.?role.orValue("") == "")
message: "Container with forbidden SELinux role"
6 changes: 1 addition & 5 deletions internal/builtins/pss/baseline/M-108_proc_mount.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,5 @@ match:
resource: jobs
validations:
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.procMount) ||
container.securityContext.procMount == 'Default'
)
allContainers.all(c, c.?securityContext.?procMount.orValue("Default") == "Default")
message: "Container using forbidden proc mount type"
12 changes: 2 additions & 10 deletions internal/builtins/pss/baseline/M-109_seccomp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,8 @@ match:
resource: jobs
validations:
- expression: >
!has(podSpec.securityContext) ||
!has(podSpec.securityContext.seccompProfile) ||
!has(podSpec.securityContext.seccompProfile.type) ||
podSpec.securityContext.seccompProfile.type != 'Unconfined'
podSpec.?securityContext.?seccompProfile.?type.orValue("") != "Unconfined"
message: "Pod using forbidden seccomp profile"
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.seccompProfile) ||
!has(container.securityContext.seccompProfile.type) ||
container.securityContext.seccompProfile.type != 'Unconfined'
)
allContainers.all(c, c.?securityContext.?seccompProfile.?type.orValue("") != "Unconfined")
message: "Container using forbidden seccomp profile"
7 changes: 4 additions & 3 deletions internal/builtins/pss/baseline/M-110_sysctls.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ params:
- net.ipv4.ip_unprivileged_port_start
- net.ipv4.tcp_syncookies
- net.ipv4.ping_group_range
variables:
- name: sysctls
expression: podSpec.?securityContext.?sysctls.orValue([])
validations:
- expression: >
!has(podSpec.securityContext) ||
!has(podSpec.securityContext.sysctls) ||
podSpec.securityContext.sysctls.all(s,
variables.sysctls.size() == 0 || variables.sysctls.all(s,
s.name == null ||
s.name in params.allowedSysctls
)
Expand Down
8 changes: 5 additions & 3 deletions internal/builtins/pss/restricted/M-111_volume_types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ params:
- persistentVolumeClaim
- projected
- secret
variables:
- name: volumes
expression: podSpec.?volumes.orValue([])
validations:
- expression: >
!has(podSpec.volumes) ||
podSpec.volumes.all(volume,
volume.exists(key, key in params.allowedVolumeTypes)
variables.volumes.size() == 0 || variables.volumes.all(v,
v.exists(key, key in params.allowedVolumeTypes)
)
message: "Not allowed volume type used"
10 changes: 4 additions & 6 deletions internal/builtins/pss/restricted/M-112_privilege_escalation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@ match:
- group: batch
version: v1
resource: jobs
variables:
- name: isWindows
expression: podSpec.?os.?name.orValue("") == "windows"
validations:
- expression: >
allContainers.all(container,
!has(container.securityContext) ||
!has(container.securityContext.allowPrivilegeEscalation) ||
container.securityContext.allowPrivilegeEscalation == false
)
message: "Container with allowed privilege escalation"
variables.isWindows || allContainers.all(c, c.?securityContext.?allowPrivilegeEscalation.orValue(true) == false)
Loading