forked from ComplianceAsCode/content
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #56 from sig-bsi-grundschutz/bsi-app-4.4-a8to11
Bsi app 4.4 a8to11
- Loading branch information
Showing
28 changed files
with
889 additions
and
34 deletions.
There are no files selected for viewing
52 changes: 52 additions & 0 deletions
52
...tions/openshift/accounts/accounts_no_clusterrolebindings_default_service_account/rule.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
documentation_complete: true | ||
|
||
title: 'Ensure no ClusterRoleBindings set for default Service Account' | ||
|
||
description: |- | ||
Using the <tt>default</tt> service account prevents accurate application | ||
rights review and audit tracing. Instead of <tt>default</tt>, create | ||
a new and unique service account and associate the required ClusterRoleBindings. | ||
rationale: |- | ||
Kubernetes provides a default service account which is used by | ||
cluster workloads where no specific service account is assigned to the pod. | ||
Where access to the Kubernetes API from a pod is required, a specific service account | ||
should be created for that pod, and rights granted to that service account. | ||
This increases auditability of service account rights and access making it | ||
easier and more accurate to trace potential malicious behaviors to a specific | ||
service account and project. | ||
severity: medium | ||
|
||
identifiers: {} | ||
|
||
references: | ||
bsi: APP.4.4.A9 | ||
|
||
{{% set jqfilter = '[.items[] | select ( .subjects[]?.name == "default" ) | select(.subjects[].namespace | startswith("kube-") or startswith("openshift-") | not) | .metadata.name ] | unique' %}} | ||
|
||
ocil_clause: 'default service account is given permissions using ClusterRoleBindings' | ||
|
||
ocil: |- | ||
Run the following command to retrieve a list of ClusterRoleBindings that are | ||
associated to the default service account: | ||
<pre>$ oc get clusterrolebindings -o json | jq '{{{ jqfilter }}}'</pre> | ||
There should be no ClusterRoleBindings associated with the the default service account | ||
in any namespace. | ||
warnings: | ||
- general: |- | ||
{{{ openshift_filtered_cluster_setting({'/apis/rbac.authorization.k8s.io/v1/clusterrolebindings?limit=10000': jqfilter}) | indent(4) }}} | ||
template: | ||
name: yamlfile_value | ||
vars: | ||
ocp_data: "true" | ||
filepath: |- | ||
{{{ openshift_filtered_path('/apis/rbac.authorization.k8s.io/v1/clusterrolebindings?limit=10000', jqfilter) }}} | ||
yamlpath: "[:]" | ||
check_existence: "none_exist" | ||
entity_check: "all" | ||
values: | ||
- value: "(.*?)" | ||
operation: "pattern match" |
128 changes: 128 additions & 0 deletions
128
...ebindings_default_service_account/tests/clusterrolebindings_other_serviceaccounts.pass.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#!/bin/bash | ||
# remediation = none | ||
# packages = jq | ||
|
||
kube_apipath="/kubernetes-api-resources" | ||
mkdir -p "$kube_apipath/apis/rbac.authorization.k8s.io/v1" | ||
crb_apipath="/apis/rbac.authorization.k8s.io/v1/clusterrolebindings?limit=10000" | ||
|
||
cat <<EOF > "$kube_apipath$crb_apipath" | ||
{ | ||
"apiVersion": "v1", | ||
"items": [ | ||
{ | ||
"apiVersion": "rbac.authorization.k8s.io/v1", | ||
"kind": "ClusterRoleBinding", | ||
"metadata": { | ||
"creationTimestamp": "2023-11-07T10:07:21Z", | ||
"labels": { | ||
"app": "controller.csi.trident.netapp.io", | ||
"k8s_version": "v1.25.14", | ||
"trident_version": "v23.01.0" | ||
}, | ||
"name": "trident-controller", | ||
"ownerReferences": [ | ||
{ | ||
"apiVersion": "trident.netapp.io/v1", | ||
"controller": true, | ||
"kind": "TridentOrchestrator", | ||
"name": "trident", | ||
"uid": "eb7fe92c-3378-4d27-98a1-d4b543772e3c" | ||
} | ||
], | ||
"resourceVersion": "989379693", | ||
"uid": "8eab8cd7-8fc3-41a7-bd2a-1c9f6f7c2d8b" | ||
}, | ||
"roleRef": { | ||
"apiGroup": "rbac.authorization.k8s.io", | ||
"kind": "ClusterRole", | ||
"name": "trident-controller" | ||
}, | ||
"subjects": [ | ||
{ | ||
"kind": "ServiceAccount", | ||
"name": "trident-controller", | ||
"namespace": "trident" | ||
} | ||
] | ||
}, | ||
{ | ||
"apiVersion": "rbac.authorization.k8s.io/v1", | ||
"kind": "ClusterRoleBinding", | ||
"metadata": { | ||
"annotations": { | ||
"rbac.authorization.kubernetes.io/autoupdate": "false" | ||
}, | ||
"creationTimestamp": "2021-01-04T14:30:26Z", | ||
"labels": { | ||
"app.kubernetes.io/instance": "roles" | ||
}, | ||
"name": "self-provisioners", | ||
"resourceVersion": "268316753", | ||
"uid": "7c5ad812-cab1-40bb-88dc-a014015f7ede" | ||
}, | ||
"roleRef": { | ||
"apiGroup": "rbac.authorization.k8s.io", | ||
"kind": "ClusterRole", | ||
"name": "self-provisioner" | ||
} | ||
}, | ||
{ | ||
"apiVersion": "rbac.authorization.k8s.io/v1", | ||
"kind": "ClusterRoleBinding", | ||
"metadata": { | ||
"creationTimestamp": "2021-01-04T14:49:26Z", | ||
"name": "prometheus-k8s", | ||
"resourceVersion": "39547", | ||
"uid": "57de031f-a360-483d-903f-19f0fb597cc9" | ||
}, | ||
"roleRef": { | ||
"apiGroup": "rbac.authorization.k8s.io", | ||
"kind": "ClusterRole", | ||
"name": "prometheus-k8s" | ||
}, | ||
"subjects": [ | ||
{ | ||
"kind": "ServiceAccount", | ||
"name": "prometheus-k8s", | ||
"namespace": "openshift-monitoring" | ||
} | ||
] | ||
}, | ||
{ | ||
"apiVersion": "rbac.authorization.k8s.io/v1", | ||
"kind": "ClusterRoleBinding", | ||
"metadata": { | ||
"creationTimestamp": "2021-01-04T14:27:59Z", | ||
"name": "system:openshift:openshift-apiserver", | ||
"resourceVersion": "5623", | ||
"uid": "fe1c3593-7e89-4b2c-b47b-a6569f47d88f" | ||
}, | ||
"roleRef": { | ||
"apiGroup": "rbac.authorization.k8s.io", | ||
"kind": "ClusterRole", | ||
"name": "cluster-admin" | ||
}, | ||
"subjects": [ | ||
{ | ||
"kind": "ServiceAccount", | ||
"name": "openshift-apiserver-sa", | ||
"namespace": "openshift-apiserver" | ||
} | ||
] | ||
} | ||
], | ||
"kind": "List", | ||
"metadata": { | ||
"resourceVersion": "" | ||
} | ||
} | ||
EOF | ||
|
||
jq_filter='[.items[] | select ( .subjects[]?.name == "default" ) | select(.subjects[].namespace | startswith("kube-") or startswith("openshift-") | not) | .metadata.name ] | unique' | ||
|
||
# Get file path. This will actually be read by the scan | ||
filteredpath="$kube_apipath$crb_apipath#$(echo -n "$crb_apipath$jq_filter" | sha256sum | awk '{print $1}')" | ||
|
||
# populate filtered path with jq-filtered result | ||
jq "$jq_filter" "$kube_apipath$crb_apipath" > "$filteredpath" |
114 changes: 114 additions & 0 deletions
114
...terrolebindings_default_service_account/tests/clusterrolebindings_serviceaccounts.fail.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#!/bin/bash | ||
# remediation = none | ||
# packages = jq | ||
|
||
kube_apipath="/kubernetes-api-resources" | ||
mkdir -p "$kube_apipath/apis/rbac.authorization.k8s.io/v1" | ||
crb_apipath="/apis/rbac.authorization.k8s.io/v1/clusterrolebindings?limit=10000" | ||
|
||
# This file assumes that we dont have any clusterrolebindings. | ||
cat <<EOF > "$kube_apipath$crb_apipath" | ||
{ | ||
"apiVersion": "v1", | ||
"items": [ | ||
{ | ||
"apiVersion": "rbac.authorization.k8s.io/v1", | ||
"kind": "ClusterRoleBinding", | ||
"metadata": { | ||
"creationTimestamp": "2023-11-07T10:07:21Z", | ||
"labels": { | ||
"app": "controller.csi.trident.netapp.io", | ||
"k8s_version": "v1.25.14", | ||
"trident_version": "v23.01.0" | ||
}, | ||
"name": "trident-controller", | ||
"ownerReferences": [ | ||
{ | ||
"apiVersion": "trident.netapp.io/v1", | ||
"controller": true, | ||
"kind": "TridentOrchestrator", | ||
"name": "trident", | ||
"uid": "eb7fe92c-3378-4d27-98a1-d4b543772e3c" | ||
} | ||
], | ||
"resourceVersion": "989379693", | ||
"uid": "8eab8cd7-8fc3-41a7-bd2a-1c9f6f7c2d8b" | ||
}, | ||
"roleRef": { | ||
"apiGroup": "rbac.authorization.k8s.io", | ||
"kind": "ClusterRole", | ||
"name": "trident-controller" | ||
}, | ||
"subjects": [ | ||
{ | ||
"kind": "ServiceAccount", | ||
"name": "trident-controller", | ||
"namespace": "trident" | ||
} | ||
] | ||
}, | ||
{ | ||
"apiVersion": "rbac.authorization.k8s.io/v1", | ||
"kind": "ClusterRoleBinding", | ||
"metadata": { | ||
"creationTimestamp": "2021-01-18T15:31:25Z", | ||
"name": "system:openshift:scc:anyuid", | ||
"resourceVersion": "5666124", | ||
"uid": "a85b6fd7-2d53-4e98-9c12-afc8d2e0896f" | ||
}, | ||
"roleRef": { | ||
"apiGroup": "rbac.authorization.k8s.io", | ||
"kind": "ClusterRole", | ||
"name": "system:openshift:scc:anyuid" | ||
}, | ||
"subjects": [ | ||
{ | ||
"kind": "ServiceAccount", | ||
"name": "default", | ||
"namespace": "app1" | ||
} | ||
] | ||
}, | ||
{ | ||
"apiVersion": "rbac.authorization.k8s.io/v1", | ||
"kind": "ClusterRoleBinding", | ||
"metadata": { | ||
"creationTimestamp": "2021-08-10T10:35:31Z", | ||
"name": "ds-operator-manager-rolebinding", | ||
"resourceVersion": "1116129289", | ||
"uid": "0deb4996-a03c-4428-8135-5468cb218c8f" | ||
}, | ||
"roleRef": { | ||
"apiGroup": "rbac.authorization.k8s.io", | ||
"kind": "ClusterRole", | ||
"name": "ds-operator-manager-role" | ||
}, | ||
"subjects": [ | ||
{ | ||
"kind": "ServiceAccount", | ||
"name": "default", | ||
"namespace": "ds-system" | ||
}, | ||
{ | ||
"kind": "ServiceAccount", | ||
"name": "default", | ||
"namespace": "magic-controller" | ||
} | ||
] | ||
} | ||
], | ||
"kind": "List", | ||
"metadata": { | ||
"resourceVersion": "" | ||
} | ||
} | ||
EOF | ||
|
||
|
||
jq_filter='[.items[] | select ( .subjects[]?.name == "default" ) | select(.subjects[].namespace | startswith("kube-") or startswith("openshift-") | not) | .metadata.name ] | unique' | ||
|
||
# Get file path. This will actually be read by the scan | ||
filteredpath="$kube_apipath$crb_apipath#$(echo -n "$crb_apipath$jq_filter" | sha256sum | awk '{print $1}')" | ||
|
||
# populate filtered path with jq-filtered result | ||
jq "$jq_filter" "$kube_apipath$crb_apipath" > "$filteredpath" |
29 changes: 29 additions & 0 deletions
29
...ounts_no_clusterrolebindings_default_service_account/tests/no_clusterrolebindings.pass.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/bin/bash | ||
# remediation = none | ||
# packages = jq | ||
|
||
kube_apipath="/kubernetes-api-resources" | ||
mkdir -p "$kube_apipath/apis/rbac.authorization.k8s.io/v1" | ||
crb_apipath="/apis/rbac.authorization.k8s.io/v1/clusterrolebindings?limit=10000" | ||
|
||
# This file assumes that we dont have any clusterrolebindings. | ||
cat <<EOF > "$kube_apipath$crb_apipath" | ||
{ | ||
"apiVersion": "v1", | ||
"items": [], | ||
"kind": "List", | ||
"metadata": { | ||
"resourceVersion": "", | ||
"selfLink": "" | ||
} | ||
} | ||
EOF | ||
|
||
|
||
jq_filter='[.items[] | select ( .subjects[]?.name == "default" ) | select(.subjects[].namespace | startswith("kube-") or startswith("openshift-") | not) | .metadata.name ] | unique' | ||
|
||
# Get file path. This will actually be read by the scan | ||
filteredpath="$kube_apipath$crb_apipath#$(echo -n "$crb_apipath$jq_filter" | sha256sum | awk '{print $1}')" | ||
|
||
# populate filtered path with jq-filtered result | ||
jq "$jq_filter" "$kube_apipath$crb_apipath" > "$filteredpath" |
2 changes: 2 additions & 0 deletions
2
...shift/accounts/accounts_no_clusterrolebindings_default_service_account/tests/ocp4/e2e.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
--- | ||
default_result: PASS |
52 changes: 52 additions & 0 deletions
52
applications/openshift/accounts/accounts_no_rolebindings_default_service_account/rule.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
documentation_complete: true | ||
|
||
title: 'Ensure no RoleBindings set for default Service Account' | ||
|
||
description: |- | ||
Using the <tt>default</tt> service account prevents accurate application | ||
rights review and audit tracing. Instead of <tt>default</tt>, create | ||
a new and unique service account and associate the required RoleBindings. | ||
rationale: |- | ||
Kubernetes provides a default service account which is used by | ||
cluster workloads where no specific service account is assigned to the pod. | ||
Where access to the Kubernetes API from a pod is required, a specific service account | ||
should be created for that pod, and rights granted to that service account. | ||
This increases auditability of service account rights and access making it | ||
easier and more accurate to trace potential malicious behaviors to a specific | ||
service account and project. | ||
severity: medium | ||
|
||
identifiers: {} | ||
|
||
references: | ||
bsi: APP.4.4.A9 | ||
|
||
{{% set jqfilter = '[.items[] | select(.metadata.namespace | startswith("kube-") or startswith("openshift-") | not) | select ( .subjects[]?.name == "default" ) | .metadata.namespace + "/" + .metadata.name ] | unique' %}} | ||
|
||
ocil_clause: 'default service account is given permissions using RoleBindings' | ||
|
||
ocil: |- | ||
Run the following command to retrieve a list of RoleBindings that are | ||
associated to the default service account: | ||
<pre>$ oc get rolebindings --all-namespaces -o json | jq '{{{ jqfilter }}}'</pre> | ||
There should be no RoleBindings associated with the the default service account | ||
in any namespace. | ||
warnings: | ||
- general: |- | ||
{{{ openshift_filtered_cluster_setting({'/apis/rbac.authorization.k8s.io/v1/rolebindings?limit=10000': jqfilter}) | indent(4) }}} | ||
template: | ||
name: yamlfile_value | ||
vars: | ||
ocp_data: "true" | ||
filepath: |- | ||
{{{ openshift_filtered_path('/apis/rbac.authorization.k8s.io/v1/rolebindings?limit=10000', jqfilter) }}} | ||
yamlpath: "[:]" | ||
check_existence: "none_exist" | ||
entity_check: "all" | ||
values: | ||
- value: "(.*?)" | ||
operation: "pattern match" |
Oops, something went wrong.