From 423f6d7d2749e9f71c4b515abbd04c4e89f70592 Mon Sep 17 00:00:00 2001 From: YiscahLevySilas1 Date: Mon, 9 Oct 2023 16:32:13 +0300 Subject: [PATCH 1/3] SUB-2185 - improve C-0262 Signed-off-by: YiscahLevySilas1 --- controls/C-0262-anonymousaccessisenabled.json | 5 ++--- rules/anonymous-access-enabled/raw.rego | 15 +++++++-------- rules/anonymous-access-enabled/rule.metadata.json | 4 ++-- .../test/fail/expected.json | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/controls/C-0262-anonymousaccessisenabled.json b/controls/C-0262-anonymousaccessisenabled.json index 97a282ca5..acc295a63 100644 --- a/controls/C-0262-anonymousaccessisenabled.json +++ b/controls/C-0262-anonymousaccessisenabled.json @@ -1,6 +1,6 @@ { "controlID": "C-0262", - "name": "Anonymous access enabled", + "name": "Anonymous user has RoleBinding", "description": "Granting permissions to the system:unauthenticated or system:anonymous user is generally not recommended and can introduce security risks. Allowing unauthenticated access to your Kubernetes cluster can lead to unauthorized access, potential data breaches, and abuse of cluster resources.", "remediation": "Review and modify your cluster's RBAC configuration to ensure that only authenticated and authorized users have appropriate permissions based on their roles and responsibilities within your system.", "test": "Checks if ClusterRoleBinding/RoleBinding resources give permissions to anonymous user. Also checks in the apiserver if the --anonymous-auth flag is set to false", @@ -8,10 +8,9 @@ "armoBuiltin": true }, "rulesNames": [ - "ensure-that-the-api-server-anonymous-auth-argument-is-set-to-false", "anonymous-access-enabled" ], - "baseScore": 5, + "baseScore": 7, "category": { "name": "Control plane", "subCategory": { diff --git a/rules/anonymous-access-enabled/raw.rego b/rules/anonymous-access-enabled/raw.rego index 235f25196..abec9e122 100644 --- a/rules/anonymous-access-enabled/raw.rego +++ b/rules/anonymous-access-enabled/raw.rego @@ -4,12 +4,14 @@ package armo_builtins deny[msga] { rolebindings := [rolebinding | rolebinding = input[_]; endswith(rolebinding.kind, "Binding")] rolebinding := rolebindings[_] - - isAnonymous(rolebinding) - + subject := rolebinding.subjects[i] + isAnonymous(subject) + delete_path := sprintf("subjects[%d]", [i]) msga := { "alertMessage": sprintf("the following RoleBinding: %v gives permissions to anonymous users", [rolebinding.metadata.name]), "alertScore": 9, + "deletePaths": [delete_path], + "failedPaths": [delete_path], "packagename": "armo_builtins", "alertObject": { "k8sApiObjects": [rolebinding] @@ -18,13 +20,10 @@ deny[msga] { } -isAnonymous(binding) { - subject := binding.subjects[_] +isAnonymous(subject) { subject.name == "system:anonymous" } - -isAnonymous(binding) { - subject := binding.subjects[_] +isAnonymous(subject) { subject.name == "system:unauthenticated" } diff --git a/rules/anonymous-access-enabled/rule.metadata.json b/rules/anonymous-access-enabled/rule.metadata.json index eb6793735..a05140e70 100644 --- a/rules/anonymous-access-enabled/rule.metadata.json +++ b/rules/anonymous-access-enabled/rule.metadata.json @@ -19,7 +19,7 @@ } ], "ruleDependencies": [], - "description": "Fails in case anonymous access is enabled on the cluster", - "remediation": "Disable anonymous access by passing the --anonymous-auth=false flag to the kube-apiserver component, or if it's a managed cluster, you can remove any RBAC rules which allow anonymous users to perform actions", + "description": "Fails in case anonymous or unauthenticated user has any rbac permissions (is bound by a RoleBinding/ClusterRoleBinding", + "remediation": "Remove any RBAC rules which allow anonymous users to perform actions", "ruleQuery": "armo_builtins" } diff --git a/rules/anonymous-access-enabled/test/fail/expected.json b/rules/anonymous-access-enabled/test/fail/expected.json index 785972a18..f3757ef2f 100644 --- a/rules/anonymous-access-enabled/test/fail/expected.json +++ b/rules/anonymous-access-enabled/test/fail/expected.json @@ -1,7 +1,7 @@ [ { "alertMessage": "the following RoleBinding: system:public-info-viewer gives permissions to anonymous users", - "failedPaths": null, + "failedPaths": ["subjects[1]"], "fixPaths": null, "ruleStatus": "", "packagename": "armo_builtins", From 895d47770c9d5537a555b51bdbca4b48fc23414b Mon Sep 17 00:00:00 2001 From: YiscahLevySilas1 Date: Mon, 9 Oct 2023 18:23:14 +0300 Subject: [PATCH 2/3] minor fix Signed-off-by: YiscahLevySilas1 --- rules/anonymous-access-enabled/rule.metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/anonymous-access-enabled/rule.metadata.json b/rules/anonymous-access-enabled/rule.metadata.json index a05140e70..ed0b38635 100644 --- a/rules/anonymous-access-enabled/rule.metadata.json +++ b/rules/anonymous-access-enabled/rule.metadata.json @@ -19,7 +19,7 @@ } ], "ruleDependencies": [], - "description": "Fails in case anonymous or unauthenticated user has any rbac permissions (is bound by a RoleBinding/ClusterRoleBinding", + "description": "Fails in case anonymous or unauthenticated user has any rbac permissions (is bound by a RoleBinding/ClusterRoleBinding)", "remediation": "Remove any RBAC rules which allow anonymous users to perform actions", "ruleQuery": "armo_builtins" } From 5bba7c23bbd69942de73e2974d6e4deb4ae5733a Mon Sep 17 00:00:00 2001 From: YiscahLevySilas1 Date: Thu, 12 Oct 2023 17:16:42 +0300 Subject: [PATCH 3/3] add [] to fixpath Signed-off-by: YiscahLevySilas1 --- rules/k8s-common-labels-usage/raw.rego | 6 +++--- rules/k8s-common-labels-usage/test/cronjob/expected.json | 2 +- rules/k8s-common-labels-usage/test/pod/expected.json | 2 +- .../test/workload-fail/expected.json | 2 +- rules/label-usage-for-resources/raw.rego | 6 +++--- rules/label-usage-for-resources/test/cronjob/expected.json | 2 +- .../test/workload-fail/expected.json | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rules/k8s-common-labels-usage/raw.rego b/rules/k8s-common-labels-usage/raw.rego index 238b41216..7a6a29c7e 100644 --- a/rules/k8s-common-labels-usage/raw.rego +++ b/rules/k8s-common-labels-usage/raw.rego @@ -87,21 +87,21 @@ no_K8s_label_usage(wl, podSpec, beggining_of_pod_path) = path{ no_K8s_label_or_no_K8s_label_usage(wl, start_of_path) = path{ not wl.metadata.labels label_key := get_label_key("") - path = [{"path": sprintf("%vmetadata.labels.%v", [start_of_path, label_key]), "value": "YOUR_VALUE"}] + path = [{"path": sprintf("%vmetadata.labels[%v]", [start_of_path, label_key]), "value": "YOUR_VALUE"}] } no_K8s_label_or_no_K8s_label_usage(wl, start_of_path) = path{ metadata := wl.metadata not metadata.labels label_key := get_label_key("") - path = [{"path": sprintf("%vmetadata.labels.%v", [start_of_path, label_key]), "value": "YOUR_VALUE"}] + path = [{"path": sprintf("%vmetadata.labels[%v]", [start_of_path, label_key]), "value": "YOUR_VALUE"}] } no_K8s_label_or_no_K8s_label_usage(wl, start_of_path) = path{ labels := wl.metadata.labels not all_kubernetes_labels(labels) label_key := get_label_key("") - path = [{"path": sprintf("%vmetadata.labels.%v", [start_of_path, label_key]), "value": "YOUR_VALUE"}] + path = [{"path": sprintf("%vmetadata.labels[%v]", [start_of_path, label_key]), "value": "YOUR_VALUE"}] } all_kubernetes_labels(labels){ diff --git a/rules/k8s-common-labels-usage/test/cronjob/expected.json b/rules/k8s-common-labels-usage/test/cronjob/expected.json index 2f9d26829..39bd3724c 100644 --- a/rules/k8s-common-labels-usage/test/cronjob/expected.json +++ b/rules/k8s-common-labels-usage/test/cronjob/expected.json @@ -2,7 +2,7 @@ "alertMessage": "the following cronjobs the kubernetes common labels are not defined: hello", "failedPaths": [], "fixPaths": [{ - "path": "spec.jobTemplate.spec.template.metadata.labels.app.kubernetes.io/name", + "path": "spec.jobTemplate.spec.template.metadata.labels[app.kubernetes.io/name]", "value": "YOUR_VALUE" }], "ruleStatus": "", diff --git a/rules/k8s-common-labels-usage/test/pod/expected.json b/rules/k8s-common-labels-usage/test/pod/expected.json index 2a4cac865..ee876ef1b 100644 --- a/rules/k8s-common-labels-usage/test/pod/expected.json +++ b/rules/k8s-common-labels-usage/test/pod/expected.json @@ -2,7 +2,7 @@ "alertMessage": "in the following pod the kubernetes common labels are not defined: command-demo", "failedPaths": [], "fixPaths": [{ - "path": "metadata.labels.YOUR_LABEL", + "path": "metadata.labels[YOUR_LABEL]", "value": "YOUR_VALUE" }], "ruleStatus": "", diff --git a/rules/k8s-common-labels-usage/test/workload-fail/expected.json b/rules/k8s-common-labels-usage/test/workload-fail/expected.json index 3a98cdfa0..105929639 100644 --- a/rules/k8s-common-labels-usage/test/workload-fail/expected.json +++ b/rules/k8s-common-labels-usage/test/workload-fail/expected.json @@ -2,7 +2,7 @@ "alertMessage": "Deployment: kubernetes-dashboard the kubernetes common labels are is not defined:", "failedPaths": [], "fixPaths": [{ - "path": "spec.template.metadata.labels.app.kubernetes.io/name", + "path": "spec.template.metadata.labels[app.kubernetes.io/name]", "value": "YOUR_VALUE" }], "ruleStatus": "", diff --git a/rules/label-usage-for-resources/raw.rego b/rules/label-usage-for-resources/raw.rego index a8f8e82e8..06047c3b5 100644 --- a/rules/label-usage-for-resources/raw.rego +++ b/rules/label-usage-for-resources/raw.rego @@ -85,21 +85,21 @@ no_label_usage(wl, podSpec, beggining_of_pod_path) = path{ no_label_or_no_label_usage(wl, start_of_path) = path{ not wl.metadata label_key := get_label_key("") - path = [{"path": sprintf("%vmetadata.labels.%v", [start_of_path, label_key]), "value": "YOUR_VALUE"}] + path = [{"path": sprintf("%vmetadata.labels[%v]", [start_of_path, label_key]), "value": "YOUR_VALUE"}] } no_label_or_no_label_usage(wl, start_of_path) = path{ metadata := wl.metadata not metadata.labels label_key := get_label_key("") - path = [{"path": sprintf("%vmetadata.labels.%v", [start_of_path, label_key]), "value": "YOUR_VALUE"}] + path = [{"path": sprintf("%vmetadata.labels[%v]", [start_of_path, label_key]), "value": "YOUR_VALUE"}] } no_label_or_no_label_usage(wl, start_of_path) = path{ labels := wl.metadata.labels not is_desired_label(labels) label_key := get_label_key("") - path = [{"path": sprintf("%vmetadata.labels.%v", [start_of_path, label_key]), "value": "YOUR_VALUE"}] + path = [{"path": sprintf("%vmetadata.labels[%v]", [start_of_path, label_key]), "value": "YOUR_VALUE"}] } is_desired_label(labels) { diff --git a/rules/label-usage-for-resources/test/cronjob/expected.json b/rules/label-usage-for-resources/test/cronjob/expected.json index 595a928d3..b541a4f03 100644 --- a/rules/label-usage-for-resources/test/cronjob/expected.json +++ b/rules/label-usage-for-resources/test/cronjob/expected.json @@ -5,7 +5,7 @@ "path": "metadata.labels.YOUR_LABEL", "value": "YOUR_VALUE" }, { - "path": "spec.jobTemplate.spec.template.metadata.labels.YOUR_LABEL", + "path": "spec.jobTemplate.spec.template.metadata.labels[YOUR_LABEL]", "value": "YOUR_VALUE" }], "ruleStatus": "", diff --git a/rules/label-usage-for-resources/test/workload-fail/expected.json b/rules/label-usage-for-resources/test/workload-fail/expected.json index dcf7acfeb..ff103d96a 100644 --- a/rules/label-usage-for-resources/test/workload-fail/expected.json +++ b/rules/label-usage-for-resources/test/workload-fail/expected.json @@ -2,7 +2,7 @@ "alertMessage": "Deployment: kubernetes-dashboard a certain set of labels is not defined:", "failedPaths": [], "fixPaths": [{ - "path": "spec.template.metadata.labels.app", + "path": "spec.template.metadata.labels[app]", "value": "YOUR_VALUE" }], "ruleStatus": "",