diff --git a/cloud/kubernetes/deployments/k8s-cpu-limits-not-set.yaml b/cloud/kubernetes/deployments/k8s-cpu-limits-not-set.yaml index 1211e7285d..7daf55f8d7 100644 --- a/cloud/kubernetes/deployments/k8s-cpu-limits-not-set.yaml +++ b/cloud/kubernetes/deployments/k8s-cpu-limits-not-set.yaml @@ -46,4 +46,4 @@ javascript: - type: dsl dsl: - response -# digest: 490a0046304402205d1ddc90198898e6c233e5aac1742de397db7c2a70008e5fbc0676562a86894d0220088faf06d908f7d7dd8c9d0de8a20a120ed129962c78ce589abff2bc9402014a:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 490a0046304402207794d2cf587203ba357f4376862e445b2f8612f8fb9eee2683d45f445f4a450d02206387d8f375f6157ef9ac572a2595210e717fef4fcd935b5a7f243f806bea47f4:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/deployments/k8s-host-ports-check.yaml b/cloud/kubernetes/deployments/k8s-host-ports-check.yaml new file mode 100644 index 0000000000..0d8fb6bd3b --- /dev/null +++ b/cloud/kubernetes/deployments/k8s-host-ports-check.yaml @@ -0,0 +1,50 @@ +id: k8s-host-ports-check + +info: + name: Host ports should not be used + author: princechaddha + severity: medium + description: Checks Kubernetes Deployments to ensure they are not configured to use host ports, which can expose the host to potential security risks. + impact: | + Using host ports can compromise the isolation between the host and the containers, increasing the risk of unauthorized access to host resources. This can lead to security breaches. + remediation: | + Avoid using host ports in Kubernetes Deployments. Use services or other networking mechanisms to expose container applications. + reference: + - https://kubernetes.io/docs/concepts/services-networking/service/ + tags: cloud,devops,kubernetes,security,devsecops,deployments + +flow: | + code(1); + for (let deployment of template.items) { + set("deployment", deployment) + javascript(1); + } + +self-contained: true +code: + - engine: + - sh + - bash + source: kubectl get deployments --all-namespaces --output=json + extractors: + - type: json + name: items + internal: true + json: + - '.items[] | {name: .metadata.name, namespace: .metadata.namespace, containers: .spec.template.spec.containers}' + +javascript: + - code: | + let deploymentData = JSON.parse(template.deployment); + deploymentData.containers.forEach(container => { + if (container.ports && container.ports.some(port => port.hostPort)) { + let result = (`Deployment '${deploymentData.name}' in namespace '${deploymentData.namespace}' uses host ports.`); + Export(result); + } + }); + + extractors: + - type: dsl + dsl: + - response +# digest: 4b0a00483046022100f3a3753e5b3711de8e19eb7d96fe6cb9bbb71ea0d38975957c40c504f3469967022100c210bc6cb2adbcf0da1de9cd21c812ec890563c3cd8bb2edc76196cd311aecbd:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/deployments/k8s-image-pull-policy-always.yaml b/cloud/kubernetes/deployments/k8s-image-pull-policy-always.yaml index 0a4adf49b8..17c192b3af 100644 --- a/cloud/kubernetes/deployments/k8s-image-pull-policy-always.yaml +++ b/cloud/kubernetes/deployments/k8s-image-pull-policy-always.yaml @@ -45,4 +45,4 @@ javascript: - type: dsl dsl: - response -# digest: 4a0a004730450220107f47e2cbc8e9728548ec55c0d38b8a766eee58f47d2ef94709c87fb4080509022100b074dd509ae27478b66fa9d6157e952ce3f1764f66d70df3ad45afff361bf0cb:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 4a0a0047304502200409430ae2d1311531b8e20737a1b5d8b93a3a57d0ddffa0003d34a99a4a06dd022100964eda202924507b711a38850dcae155eb2d3966b48557787e2c0e5a60c58e64:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/deployments/k8s-image-tag-not-fixed.yaml b/cloud/kubernetes/deployments/k8s-image-tag-not-fixed.yaml index 7fffa3f8be..989b5b2759 100644 --- a/cloud/kubernetes/deployments/k8s-image-tag-not-fixed.yaml +++ b/cloud/kubernetes/deployments/k8s-image-tag-not-fixed.yaml @@ -49,4 +49,4 @@ javascript: - type: dsl dsl: - response -# digest: 4a0a00473045022100bd8016086ff77ceec6ef9605c3ceccd549832cca05a8682c4f3700baa158d0c7022042bb21d930467ea83c19d742cdb8a4c271c91267eb97375ac82cf945df9c27f6:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 4b0a00483046022100a73d7f300303791070156f087c9a729d56361a04a4c2f11adb16ce3c66addd30022100e1ecf1ead4985f23fdbe80dafb0954bc5c17be9d036573d2cd40494c1fcddd7e:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/deployments/k8s-liveness-probe-not-configured.yaml b/cloud/kubernetes/deployments/k8s-liveness-probe-not-configured.yaml index 0b6043df6b..dc4f612553 100644 --- a/cloud/kubernetes/deployments/k8s-liveness-probe-not-configured.yaml +++ b/cloud/kubernetes/deployments/k8s-liveness-probe-not-configured.yaml @@ -44,4 +44,4 @@ javascript: - type: dsl dsl: - response -# digest: 4b0a00483046022100e60638756964bc77d262b7457ee93f07c60fcfdfb8b8c9713be764334cba3d8e02210098435e5cb2898c8f1bbf07c33827dc5bde729593d17cbaa029e7acb9e7d55bda:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 490a0046304402200d2e45e711a22fa4ab57ff3065de5eb87f78aa2904b41e829e3566b04de8109e02206750a88213ad16e78ffaf03980b9b7a6994acb71bdebaf83292d6608fa07a130:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/deployments/k8s-memory-limits-not-set.yaml b/cloud/kubernetes/deployments/k8s-memory-limits-not-set.yaml index cfbf4e5252..c8d50de6d9 100644 --- a/cloud/kubernetes/deployments/k8s-memory-limits-not-set.yaml +++ b/cloud/kubernetes/deployments/k8s-memory-limits-not-set.yaml @@ -44,4 +44,4 @@ javascript: - type: dsl dsl: - response -# digest: 490a0046304402205488e0d1d8975da93c8879b2f4a090004db84f9a75618b7454a62edc8b0b6c2202207555edc45bffad32c1d89b0e68ebbd836a588de88a0e2f71f201fbda052d023e:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 4a0a0047304502203a66813cc15b12b1260c6862926c6748694a84bc66c9ca24dff7052f998b5aaf022100ef69cce9aba0cb47d58dd0bc916ee54f02a32632a4749e98e7a22e3b92da0e8d:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/deployments/k8s-root-container-admission.yaml b/cloud/kubernetes/deployments/k8s-root-container-admission.yaml index 65f2b0b327..6dedcd1369 100644 --- a/cloud/kubernetes/deployments/k8s-root-container-admission.yaml +++ b/cloud/kubernetes/deployments/k8s-root-container-admission.yaml @@ -45,4 +45,4 @@ javascript: - type: dsl dsl: - response -# digest: 4a0a0047304502200475eac5bae9aa7fe9c98e0a90aa3680da94db7a15515256680d16a9fa319f8d022100b70835b10aa49e8a2961b2d957e41cc8e37f64cd066f36e292eb681900c19133:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 4a0a0047304502203296d04807538e04f058f6bbf7241e04ed2bf22ece4282aca6a268d9463a86cf022100abe93bb221464d568cbeb7cf07d382ea36e6987e9dca958912f6231b6c4e2cdf:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/network-policies/k8s-def-egress-rules.yaml b/cloud/kubernetes/network-policies/k8s-def-egress-rules.yaml new file mode 100644 index 0000000000..e6c88c2c1d --- /dev/null +++ b/cloud/kubernetes/network-policies/k8s-def-egress-rules.yaml @@ -0,0 +1,48 @@ +id: k8s-def-egress-rules + +info: + name: Ensure egress rules are defined + author: princechaddha + severity: medium + description: Checks for network policies that define specific egress rules, ensuring controlled outbound traffic. + impact: | + Lack of egress rules in network policies may allow unrestricted outbound network traffic. This can lead to potential security risks, including data exfiltration. + remediation: | + Define egress rules in the network policy to manage and restrict outbound traffic effectively. Specify allowed destinations and ports to limit network traffic. + reference: + - https://kubernetes.io/docs/concepts/services-networking/network-policies/ + tags: cloud,devops,kubernetes,security,devsecops,network + +flow: | + code(1); + for (let policy of template.items) { + set("policy", policy) + javascript(1); + } + +self-contained: true +code: + - engine: + - sh + - bash + source: kubectl get networkpolicies --all-namespaces --output=json + extractors: + - type: json + name: items + internal: true + json: + - '.items[] | {name: .metadata.name, namespace: .metadata.namespace, egress: .spec.egress}' + +javascript: + - code: | + let policyData = template.policy; + if (!policyData.egress || policyData.egress.length === 0) { + let result = `Network policy '${policyData.name}' in namespace '${policyData.namespace}' does not define any egress rules.`; + Export(result); + } + + extractors: + - type: dsl + dsl: + - response +# digest: 490a0046304402203da66eea889668b34e537e161930c32db95c287c91bf4b25ea42fab9207aa20b022066509c25e5056f4f842cc9720a481689aaf3c3208c6f91ce5dd051819e0325a6:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/network-policies/k8s-network-ingress-rules.yaml b/cloud/kubernetes/network-policies/k8s-network-ingress-rules.yaml new file mode 100644 index 0000000000..77a341ebdb --- /dev/null +++ b/cloud/kubernetes/network-policies/k8s-network-ingress-rules.yaml @@ -0,0 +1,47 @@ +id: k8s-network-ingress-rules + +info: + name: Network policies define ingress + author: princechaddha + severity: medium + description: Ensures network policies define ingress rules to control traffic flow within the cluster, enhancing security. + impact: | + Without defined ingress rules, network policies might allow unrestricted inbound traffic, potentially exposing the cluster to security threats. Properly defined ingress rules help mitigate this risk by restricting traffic flow. + remediation: Define ingress rules in network policies to restrict and control inbound traffic within the Kubernetes cluster. + reference: + - https://kubernetes.io/docs/concepts/services-networking/network-policies/ + tags: cloud,devops,kubernetes,security,devsecops,networking + +flow: | + code(1); + for (let networkPolicy of template.items) { + set("networkPolicy", networkPolicy) + javascript(1); + } + +self-contained: true +code: + - engine: + - sh + - bash + source: kubectl get networkpolicies --all-namespaces --output=json + extractors: + - type: json + name: items + internal: true + json: + - '.items[]' + +javascript: + - code: | + let networkPolicy = JSON.parse(template.networkPolicy); + if (!networkPolicy.spec.ingress || networkPolicy.spec.ingress.length === 0) { + let result = (`Network policy '${networkPolicy.metadata.name}' in namespace '${networkPolicy.metadata.namespace}' does not define any ingress rules.`); + Export(result); + } + + extractors: + - type: dsl + dsl: + - response +# digest: 4a0a00473045022100c53e3615f3c1dd115d8efd4e9415177289e366c07ee24d4694d19c882c77044102203ce3bd2c002e4ab82073e7c770d39298407a1c40246b5c657104d01b4f642f6a:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/network-policies/k8s-ns-policy-set.yaml b/cloud/kubernetes/network-policies/k8s-ns-policy-set.yaml new file mode 100644 index 0000000000..4e11702e52 --- /dev/null +++ b/cloud/kubernetes/network-policies/k8s-ns-policy-set.yaml @@ -0,0 +1,55 @@ +id: k8s-ns-policy-set + +info: + name: Network policies specify namespace + author: princechaddha + severity: medium + description: Checks for Kubernetes network policies that do not specify a namespace, potentially leading to misconfigurations and security risks. + impact: | + Failure to specify a namespace in network policies can cause the policies to not be enforced as expected, leading to potential security vulnerabilities where unauthorized traffic could be allowed. + remediation: | + Ensure that all network policies explicitly define the namespace they apply to. This helps in enforcing security boundaries and preventing cross-namespace traffic unless explicitly allowed. + reference: + - https://kubernetes.io/docs/concepts/services-networking/network-policies/ + tags: cloud,devops,kubernetes,security,devsecops,networking + +flow: | + code(1); + for (let policy of template.items) { + set("policy", policy) + javascript(1); + } + +self-contained: true +code: + - engine: + - sh + - bash + source: kubectl get networkpolicies --all-namespaces --output=json + extractors: + - type: json + name: items + internal: true + json: + - '.items[] | {policy: .metadata.name, namespace: .metadata.namespace}' + +javascript: + - code: | + if (template.items.length === 0) { + log(template.items.length) + Export('No network policies found. Ensure that network policies are defined and namespaces are specified.'); + } else { + template.items.forEach(policy => { + let policyData = JSON.parse(policy); + if (!policyData.namespace) { + let result = (`Network Policy '${policyData.policy}' does not specify a namespace.`); + Export(result); + } + }); + } + + extractors: + - type: dsl + dsl: + - response +# digest: 4a0a0047304502204f78530d043f4ee9c2844ef6ea271cdee74ef99154f17f43f120ff4cad1ff417022100dc262780f80d0e64648e5fa555c35032837ae0ecd21c274df318d593c2a1a626:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/pods/k8s-allow-privilege-escalation-set.yaml b/cloud/kubernetes/pods/k8s-allow-privilege-escalation-set.yaml index e45a1030af..cde9f87928 100644 --- a/cloud/kubernetes/pods/k8s-allow-privilege-escalation-set.yaml +++ b/cloud/kubernetes/pods/k8s-allow-privilege-escalation-set.yaml @@ -47,4 +47,4 @@ javascript: - type: dsl dsl: - response -# digest: 4a0a00473045022025dc0e9a5d93ac04821b70467991a867158ff37e94f154ac26b67c9ebfaf6bdd02210094dde6b68d08983ae386767c31909fb6aa2a8edc5f257b81309eda1d5b0b0bb9:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 490a00463044022022d7414cae87fa28332a6a123d954251d677ec6d3900d9695773585fa2659b1c02200c516a4fac6f46fc00bea745add53ff77b6f95557fceb66c8227ba2d1771ea45:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/pods/k8s-containers-share-host-ipc.yaml b/cloud/kubernetes/pods/k8s-containers-share-host-ipc.yaml index d33d13d18a..ead59c806a 100644 --- a/cloud/kubernetes/pods/k8s-containers-share-host-ipc.yaml +++ b/cloud/kubernetes/pods/k8s-containers-share-host-ipc.yaml @@ -44,4 +44,4 @@ javascript: - type: dsl dsl: - response -# digest: 4a0a00473045022100a9730fb29a79c4eb4576ddb1000e7a07cce3aa571fc20f8985265f114f5072ad02207a866c1c532b29932da349c0e29fb008675438fb327c0dab1620893ccf009ff7:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 4b0a00483046022100cc2146147ae70fb4bfc9d107d68d692ac4a287dfdaebfb356b425af0761eda00022100a8262c6003997d011ca625ceb8c1f8cc5e245c64c7306870001756811b39889b:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/pods/k8s-host-network-namespace-shared.yaml b/cloud/kubernetes/pods/k8s-host-network-namespace-shared.yaml index 6564d3b93f..a98680cc00 100644 --- a/cloud/kubernetes/pods/k8s-host-network-namespace-shared.yaml +++ b/cloud/kubernetes/pods/k8s-host-network-namespace-shared.yaml @@ -44,4 +44,4 @@ javascript: - type: dsl dsl: - response -# digest: 4b0a004830460221008eef4a8e8215cf69d36f0d94aa83b3531ce19730942b461b27842147f7f39973022100dfc800230845da0fe800dac62b006dc4a27d52a9b1684e7153165782e7d3472b:366f2a24c8eb519f6968bd8801c08ebe +# digest: 4b0a00483046022100e21998047fdf04b608359872be3fd0d5767bb0a3f6a7f8c66547c2ab9943fdfc02210089231ef6e0d74220e0fa8e2cfc7eec254e48299d53bfb4abe2891748a2e3187f:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/pods/k8s-host-pid-namespace-sharing.yaml b/cloud/kubernetes/pods/k8s-host-pid-namespace-sharing.yaml index 60922965d0..e9386f6075 100644 --- a/cloud/kubernetes/pods/k8s-host-pid-namespace-sharing.yaml +++ b/cloud/kubernetes/pods/k8s-host-pid-namespace-sharing.yaml @@ -44,4 +44,4 @@ javascript: - type: dsl dsl: - response -# digest: 4b0a00483046022100cdb3127b175107266c1409c70c3318a851490bf743f92923077b0249b9090cdd022100d3371724828565a28e7003ecf9902e3deb93c074444b7a9b2d34c235f454032c:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file +# digest: 4a0a0047304502202982af00e2f77f8a8d34d3a60faa749adcc4621fcaa816c2f19f4f6fa109ef8a022100d768ba6500983f601db45742b46b488b4efee0e2e15389034b0000c2667b67d2:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/pods/k8s-readonly-fs.yaml b/cloud/kubernetes/pods/k8s-readonly-fs.yaml index 947aa40f31..520aeb5a84 100644 --- a/cloud/kubernetes/pods/k8s-readonly-fs.yaml +++ b/cloud/kubernetes/pods/k8s-readonly-fs.yaml @@ -44,3 +44,4 @@ javascript: - type: dsl dsl: - response +# digest: 4a0a00473045022100822332f29c05236643aceb706c563112c463a6fdda5a60f391aaec1308fa9e3902207c8e95c0302c1f6f85c9a8e43e719b3e52c67684e4b5806e4e9ec0c44e1bfb20:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/pods/k8s-readonly-rootfs.yaml b/cloud/kubernetes/pods/k8s-readonly-rootfs.yaml new file mode 100644 index 0000000000..2937a1f1b1 --- /dev/null +++ b/cloud/kubernetes/pods/k8s-readonly-rootfs.yaml @@ -0,0 +1,50 @@ +id: k8s-readonly-rootfs + +info: + name: Pods with read-only root filesystem + author: princechaddha + severity: medium + description: Checks for pods and containers running with a read-only root filesystem to prevent modifications to the filesystem, enhancing security. + impact: | + Running containers with a read-only root filesystem ensures that applications are not able to write to the filesystem or modify existing content. This is a common security practice to prevent malicious changes. + remediation: | + Configure all pods and containers to have their root filesystem set to read-only mode. This can be achieved by setting the securityContext.readOnlyRootFilesystem parameter to true in the pod or container configuration. + reference: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems + tags: cloud,devops,kubernetes,security,devsecops,pods,k8s + +flow: | + code(1); + for (let pod of template.items) { + set("pod", pod) + javascript(1); + } + +self-contained: true +code: + - engine: + - sh + - bash + source: kubectl get pods --all-namespaces --output=json + extractors: + - type: json + name: items + internal: true + json: + - '.items[] | {pod: .metadata.name, containers: .spec.containers}' + +javascript: + - code: | + let podData = JSON.parse(template.pod); + podData.containers.forEach(container => { + if (container.securityContext && container.securityContext.readOnlyRootFilesystem !== true) { + let result = (`Container '${container.name}' in pod '${podData.pod}' is not running with a read-only root filesystem.`); + Export(result); + } + }); + + extractors: + - type: dsl + dsl: + - response +# digest: 490a0046304402205ca1449c5ae245df848df2d8b4117966ed8fc276841e0132e2844c643179f4c9022056438a03c5cb5402b1d07b3d1d88f123559df889348d5605c01ce0aedbedaf47:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file diff --git a/cloud/kubernetes/pods/k8s-root-user-id.yaml b/cloud/kubernetes/pods/k8s-root-user-id.yaml new file mode 100644 index 0000000000..24185e320b --- /dev/null +++ b/cloud/kubernetes/pods/k8s-root-user-id.yaml @@ -0,0 +1,49 @@ +id: k8s-root-user-id + +info: + name: Pods run with root user ID + author: princechaddha + severity: low + description: Checks for pods running with the user ID of the root user, increasing security risks. + impact: | + Running pods with the root user ID can allow malicious entities to gain unnecessary privileges, leading to potential compromises in the Kubernetes environment. + remediation: Configure pods to run with a non-root user ID by setting the 'securityContext' for each container and the pod itself. + reference: + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + tags: cloud,devops,kubernetes,security,devsecops,pods + +flow: | + code(1); + for (let pod of template.items) { + set("pod", pod) + javascript(1); + } + +self-contained: true +code: + - engine: + - sh + - bash + source: kubectl get pods --all-namespaces --output=json + extractors: + - type: json + name: items + internal: true + json: + - '.items[] | {pod: .metadata.name, containers: .spec.containers}' + +javascript: + - code: | + let podData = JSON.parse(template.pod); + podData.containers.forEach(container => { + if (container.securityContext && container.securityContext.runAsUser === 0) { + let result = (`Container '${container.name}' in pod '${podData.pod}' is running with root user ID.`); + Export(result); + } + }); + + extractors: + - type: dsl + dsl: + - response +# digest: 4a0a00473045022100c1eee5714a5bba3549ccef97ba37cc178ad76f7786c90732ff49d211d1d4153802204dae0cd7ef2c634e85d3d27a7feb5c9508f4066a91f7ef56f861ed86af5bb420:366f2a24c8eb519f6968bd8801c08ebe \ No newline at end of file