feat(core): add 13 checks of Kubernetes Core service (#3315)

Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
This commit is contained in:
Sergio Garcia
2024-02-28 13:21:53 +01:00
committed by GitHub
parent effc743b6e
commit 3c4e5a14f7
40 changed files with 837 additions and 3 deletions
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_admission_hostport_containers",
"CheckTitle": "Minimize the admission of containers which use HostPorts",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "HostPorts",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers that require the use of HostPorts. This helps maintain network policy controls and reduce security risks.",
"Risk": "Permitting containers with HostPorts can bypass network policy controls, increasing the risk of unauthorized network access.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_25#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Limit the use of HostPorts in Kubernetes containers to maintain network security.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Network Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Carefully evaluate the need for HostPorts in container configurations and prefer network policies for secure communication."
}
@@ -0,0 +1,26 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_admission_hostport_containers(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = f"Pod {pod.name} does not use HostPorts."
for container in pod.containers.values():
if container.ports and "host_port" in str(container.ports):
report.status = "FAIL"
report.status_extended = (
f"Pod {pod.name} uses HostPorts in container {container.name}."
)
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_admission_windows_hostprocess_containers",
"CheckTitle": "Minimize the admission of Windows HostProcess Containers",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Windows HostProcess Containers",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of Windows containers with the hostProcess flag set to true, thus reducing the risk of privilege escalation and security breaches.",
"Risk": "Allowing Windows containers with hostProcess can lead to increased security risks due to privileged access to Windows nodes.",
"RelatedUrl": "https://kubernetes.io/docs/tasks/configure-pod-container/create-hostprocess-pod/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_1#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of Windows HostProcess containers unless essential for their operation.",
"Url": "https://kubernetes.io/docs/tasks/configure-pod-container/create-hostprocess-pod/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Carefully review the need for HostProcess containers in Windows environments and restrict their use."
}
@@ -0,0 +1,30 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_admission_windows_hostprocess_containers(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Pod {pod.name} does not have the ability to run a Windows HostProcess."
)
for container in pod.containers.values():
if (
container.security_context
and container.security_context.windows_options
and container.security_context.windows_options.host_process
):
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} has the ability to run a Windows HostProcess in container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_allowPrivilegeEscalation_containers",
"CheckTitle": "Minimize the admission of containers with allowPrivilegeEscalation",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Privilege Escalation Control",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers that have the allowPrivilegeEscalation flag set to true, preventing processes within containers from gaining additional privileges.",
"Risk": "Allowing containers with allowPrivilegeEscalation can lead to elevated privileges within the container's context, posing a security risk.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_19#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of allowPrivilegeEscalation in containers through admission control policies.",
"Url": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for containers requiring allowPrivilegeEscalation should be clearly defined and monitored."
}
@@ -0,0 +1,29 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_allowPrivilegeEscalation_containers(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Pod {pod.name} does not allow for privilege escalation."
)
for container in pod.containers.values():
if (
container.security_context
and container.security_context.allow_privilege_escalation
):
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} allows privilege escalation in container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_containers_added_capabilities",
"CheckTitle": "Minimize the admission of containers with added capabilities",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Capability Management",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers with capabilities assigned beyond the default set, mitigating the risks of container breakout attacks.",
"Risk": "Allowing containers with additional capabilities increases the risk of security breaches and container breakout attacks.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the addition of extra capabilities to containers through admission control policies.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for adding capabilities should be explicitly defined and monitored."
}
@@ -0,0 +1,28 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_containers_added_capabilities(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = f"Pod {pod.name} does not have added capabilities."
for container in pod.containers.values():
if (
container.security_context
and container.security_context.capabilities
and container.security_context.capabilities.add
):
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} has added capabilities in container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_containers_capabilities_assigned",
"CheckTitle": "Minimize the admission of containers with capabilities assigned",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Capability Assignment",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers with Linux capabilities assigned, adhering to the principle of least privilege and reducing the risk of privilege escalation.",
"Risk": "Assigning unnecessary Linux capabilities to containers increases the risk of privilege escalation and security breaches.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_34#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the assignment of Linux capabilities to containers unless essential for their operation.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Review the use of capabilities in applications and ensure that only necessary capabilities are assigned."
}
@@ -0,0 +1,33 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_containers_capabilities_assigned(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Pod {pod.name} without capabilities issues found."
)
for container in pod.containers.values():
if (
container.security_context
and container.security_context.capabilities
):
if (
container.security_context.capabilities.add
or not container.security_context.capabilities.drop
):
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} has capabilities assigned or not all dropped in container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_hostIPC_containers",
"CheckTitle": "Minimize the admission of containers wishing to share the host IPC namespace",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Host IPC Namespace",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers that share the host's IPC namespace. Containers with hostIPC can interact with processes outside of the container, potentially leading to security risks.",
"Risk": "Allowing containers to share the host's IPC namespace without strict control can lead to security risks and potential privilege escalations.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_3#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of hostIPC in containers through admission control policies.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for hostIPC containers should be clearly defined and monitored."
}
@@ -0,0 +1,21 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_hostIPC_containers(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
if pod.host_ipc:
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} is using hostIPC."
else:
report.status = "PASS"
report.status_extended = f"Pod {pod.name} is not using hostIPC."
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_hostNetwork_containers",
"CheckTitle": "Minimize the admission of containers wishing to share the host network namespace",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Host Network Namespace",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers that share the host's network namespace. Containers with hostNetwork can access local network traffic and other pods, potentially leading to security risks.",
"Risk": "Allowing containers to share the host's network namespace without strict control can lead to security risks and potential network breaches.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_4#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of hostNetwork in containers through admission control policies.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for hostNetwork containers should be clearly defined and monitored."
}
@@ -0,0 +1,21 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_hostNetwork_containers(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
if pod.host_network:
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} is using hostNetwork."
else:
report.status = "PASS"
report.status_extended = f"Pod {pod.name} is not using hostNetwork."
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_hostPID_containers",
"CheckTitle": "Minimize the admission of containers wishing to share the host process ID namespace",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Host PID Namespace",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers that share the host's process ID namespace. Containers with hostPID can inspect and interact with processes outside of the container, potentially leading to privilege escalation.",
"Risk": "Allowing containers to share the host's PID namespace without strict control can lead to security risks and potential privilege escalations.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_1#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of hostPID in containers through admission control policies.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for hostPID containers should be clearly defined and monitored."
}
@@ -0,0 +1,21 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_hostPID_containers(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
if pod.host_pid:
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} is using hostPID."
else:
report.status = "PASS"
report.status_extended = f"Pod {pod.name} is not using hostPID."
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_net_raw_capability_admission",
"CheckTitle": "Minimize the admission of containers with the NET_RAW capability",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Capability Control",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers with the potentially dangerous NET_RAW capability, which can be exploited by malicious containers.",
"Risk": "Allowing containers with NET_RAW capability increases the risk of network attacks and privilege escalation.",
"RelatedUrl": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_6#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of NET_RAW capability through admission control policies.",
"Url": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for NET_RAW capability should be clearly defined and monitored."
}
@@ -0,0 +1,27 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_net_raw_capability_admission(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = f"Pod {pod.name} does not have NET_RAW capability."
for container in pod.containers.values():
if (
container.security_context
and container.security_context.capabilities
and "NET_RAW" in container.security_context.capabilities.add
):
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} has NET_RAW capability in container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_privileged_containers",
"CheckTitle": "Minimize the admission of privileged containers",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Privileged Containers",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of privileged containers, which have access to all Linux Kernel capabilities and devices. The use of privileged containers should be controlled and restricted to specific use-cases.",
"Risk": "Permitting privileged containers by default can lead to security vulnerabilities as these containers have elevated privileges equivalent to the host.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_2#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of privileged containers through admission control policies.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for privileged containers should be clearly defined and monitored."
}
@@ -0,0 +1,26 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_privileged_containers(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Pod {pod.name} does not contain a privileged container."
)
for container in pod.containers.values():
if container.security_context and container.security_context.privileged:
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} contains a privileged container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_minimize_root_containers_admission",
"CheckTitle": "Minimize the admission of root containers",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Root User Control",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check ensures that Kubernetes clusters are configured to minimize the admission of containers running as the root user. Running containers as root increases the risk of container breakout and should be restricted.",
"Risk": "Allowing containers to run as root can lead to elevated risk of security breaches and container breakout.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_5#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict the use of root containers through admission control policies.",
"Url": "https://kubernetes.io/docs/concepts/security/pod-security-standards/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Exceptions for root containers should be clearly defined and monitored."
}
@@ -0,0 +1,27 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_minimize_root_containers_admission(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = f"Pod {pod.name} is not running as root user."
for container in pod.containers.values():
if (
container.security_context
and container.security_context.run_as_user == 0
):
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} is running as root user in container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_no_secrets_envs",
"CheckTitle": "Prefer using secrets as files over secrets as environment variables",
"CheckType": [
"Best Practice",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Secrets Management",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "KubernetesSecrets",
"Description": "This check ensures that secrets in Kubernetes are used as files rather than environment variables. Using secrets as files is safer, as it reduces the risk of exposing sensitive data through application logs.",
"Risk": "Secrets exposed as environment variables can be inadvertently logged by applications, leading to potential security breaches.",
"RelatedUrl": "https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_33#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Minimize the use of environment variable secrets and prefer mounting secrets as files for enhanced security.",
"Url": "https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-over-environment-variables"
}
},
"Categories": [
"Security",
"Configuration Management"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Mounting secrets as files allows for dynamic updates of secrets without needing to restart the pod."
}
@@ -0,0 +1,26 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_no_secrets_envs(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
report.status = "PASS"
report.status_extended = (
f"Pod {pod.name} does not contain any secret environment variables."
)
for container in pod.containers.values():
if "secretKeyRef" in str(container.env):
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} contains secret environment variables in container {container.name}."
break
findings.append(report)
return findings
@@ -0,0 +1,36 @@
{
"Provider": "kubernetes",
"CheckID": "core_seccomp_profile_docker_default",
"CheckTitle": "Ensure that the seccomp profile is set to docker/default in your pod definitions",
"CheckType": [
"Security",
"Configuration"
],
"ServiceName": "Core",
"SubServiceName": "Seccomp Profile",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "KubernetesPod",
"Description": "This check verifies that the docker/default seccomp profile is enabled in pod definitions. Enabling seccomp profiles helps restrict the set of system calls applications can make, enhancing the security of workloads in the cluster.",
"Risk": "Not using or incorrectly configuring seccomp profiles can leave containers with broader permissions, increasing the risk of malicious actions.",
"RelatedUrl": "https://kubernetes.io/docs/tutorials/clusters/seccomp/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_k8s_30#kubernetes",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Implement the docker/default seccomp profile in pod definitions for enhanced container security.",
"Url": "https://docs.docker.com/engine/security/seccomp/"
}
},
"Categories": [
"Container Security",
"Best Practices"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": "The docker/default seccomp profile may need to be adjusted if it's too restrictive for certain applications."
}
@@ -0,0 +1,27 @@
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.core.core_client import core_client
class core_seccomp_profile_docker_default(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in core_client.pods.values():
report = Check_Report_Kubernetes(self.metadata())
report.namespace = pod.namespace
report.resource_name = pod.name
report.resource_id = pod.uid
if (
pod.security_context
and pod.security_context.seccomp_profile
and pod.security_context.seccomp_profile.type == "RuntimeDefault"
):
report.status = "PASS"
report.status_extended = (
f"Pod {pod.name} has docker/default seccomp profile enabled."
)
else:
report.status = "FAIL"
report.status_extended = f"Pod {pod.name} does not have docker/default seccomp profile enabled."
findings.append(report)
return findings
@@ -1,6 +1,8 @@
from dataclasses import dataclass
from typing import List, Optional
from kubernetes import client
from kubernetes.client.models import V1PodSecurityContext, V1SecurityContext
from pydantic import BaseModel
from prowler.lib.logger import logger
@@ -23,7 +25,17 @@ class Core(KubernetesService):
pods = self.client.list_pod_for_all_namespaces()
for pod in pods.items:
pod_containers = {}
for container in pod.spec.containers:
containers = pod.spec.containers if pod.spec.containers else []
init_containers = (
pod.spec.init_containers if pod.spec.init_containers else []
)
ephemeral_containers = (
pod.spec.ephemeral_containers
if pod.spec.ephemeral_containers
else []
)
for container in containers + init_containers + ephemeral_containers:
pod_containers[container.name] = Container(
name=container.name,
image=container.image,
@@ -40,6 +52,7 @@ class Core(KubernetesService):
]
if container.env
else None,
security_context=container.security_context,
)
self.pods[pod.metadata.uid] = Pod(
name=pod.metadata.name,
@@ -52,6 +65,10 @@ class Core(KubernetesService):
status_phase=pod.status.phase,
pod_ip=pod.status.pod_ip,
host_ip=pod.status.host_ip,
host_pid=pod.spec.host_pid,
host_ipc=pod.spec.host_ipc,
host_network=pod.spec.host_network,
security_context=pod.spec.security_context,
containers=pod_containers,
)
except Exception as error:
@@ -77,15 +94,18 @@ class Core(KubernetesService):
)
class Container(BaseModel):
@dataclass
class Container:
name: str
image: str
command: Optional[List[str]]
ports: Optional[List[dict]]
env: Optional[List[dict]]
security_context: Optional[V1SecurityContext]
class Pod(BaseModel):
@dataclass
class Pod:
name: str
uid: str
namespace: str
@@ -96,6 +116,10 @@ class Pod(BaseModel):
status_phase: Optional[str]
pod_ip: Optional[str]
host_ip: Optional[str]
host_pid: Optional[str]
host_ipc: Optional[str]
host_network: Optional[str]
security_context: Optional[V1PodSecurityContext]
containers: Optional[dict]