Skip to content

Commit

Permalink
we introduced three new rego checks to the oss. These checks are curr…
Browse files Browse the repository at this point in the history
…ently part of the commercial but not included in the oss.

Additionally, there are certain checks in the oss where two checks are combined into a single check.
However, in the commercial, these checks are treated as two separate checks.
Therefore, we will be splitting the combined checks from the oss into two distinct checks to align with the commercial implementation.
  • Loading branch information
ManojShastha authored and simar7 committed Jul 28, 2023
1 parent a9ded81 commit 60ffbaf
Show file tree
Hide file tree
Showing 22 changed files with 964 additions and 29 deletions.
2 changes: 1 addition & 1 deletion avd_docs/kubernetes/general/AVD-KSV-0041/docs.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

Check whether role permits managing secrets
Viewing secrets at the cluster-scope is akin to cluster-admin in most clusters as there are typically at least one service accounts (their token stored in a secret) bound to cluster-admin directly or a role/clusterrole that gives similar permissions.

### Impact
<!-- Add Impact here -->
Expand Down
2 changes: 1 addition & 1 deletion avd_docs/kubernetes/general/AVD-KSV-0046/docs.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

Check whether role permits specific verb on wildcard resources
Full control of the cluster resources, and therefore also root on all nodes where workloads can run and has access to all pods, secrets, and data.

### Impact
<!-- Add Impact here -->
Expand Down
13 changes: 13 additions & 0 deletions avd_docs/kubernetes/general/AVD-KSV-0112/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

Full control of the resources within a namespace. In some cluster configurations, this is excessive. In others, this is normal (a gitops deployment operator like flux)

### Impact
<!-- Add Impact here -->

<!-- DO NOT CHANGE -->
{{ remediationActions }}

### Links
- https://kubernetes.io/docs/concepts/security/rbac-good-practices/


13 changes: 13 additions & 0 deletions avd_docs/kubernetes/general/AVD-KSV-0113/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

Viewing secrets at the namespace scope can lead to escalation if another service account in that namespace has a higher privileged rolebinding or clusterrolebinding bound.

### Impact
<!-- Add Impact here -->

<!-- DO NOT CHANGE -->
{{ remediationActions }}

### Links
- https://kubernetes.io/docs/concepts/security/rbac-good-practices/


13 changes: 13 additions & 0 deletions avd_docs/kubernetes/general/AVD-KSV-0114/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

Webhooks can silently intercept or actively mutate/block resources as they are being created or updated. This includes secrets and pod specs.

### Impact
<!-- Add Impact here -->

<!-- DO NOT CHANGE -->
{{ remediationActions }}

### Links
- https://kubernetes.io/docs/concepts/security/rbac-good-practices/


13 changes: 13 additions & 0 deletions avd_docs/kubernetes/general/AVD-KSV-0115/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

Ability to add AWS IAM to RBAC bindings via special EKS configmap.

### Impact
<!-- Add Impact here -->

<!-- DO NOT CHANGE -->
{{ remediationActions }}

### Links
- https://kubernetes.io/docs/concepts/security/rbac-good-practices/


13 changes: 13 additions & 0 deletions avd_docs/kubernetes/general/AVD-KSV-0116/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.

### Impact
<!-- Add Impact here -->

<!-- DO NOT CHANGE -->
{{ remediationActions }}

### Links
- https://kubesec.io/basics/containers-securitycontext-runasuser/


12 changes: 6 additions & 6 deletions pkg/scanners/helm/test/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func Test_helm_scanner_with_archive(t *testing.T) {
require.NotNil(t, results)

failed := results.GetFailed()
assert.Equal(t, 13, len(failed))
assert.Equal(t, 18, len(failed))

visited := make(map[string]bool)
var errorCodes []string
Expand All @@ -67,7 +67,7 @@ func Test_helm_scanner_with_archive(t *testing.T) {
"AVD-KSV-0011", "AVD-KSV-0012", "AVD-KSV-0014",
"AVD-KSV-0015", "AVD-KSV-0016", "AVD-KSV-0018",
"AVD-KSV-0020", "AVD-KSV-0021", "AVD-KSV-0030",
"AVD-KSV-0104", "AVD-KSV-0106",
"AVD-KSV-0106",
}, errorCodes)
}
}
Expand Down Expand Up @@ -127,7 +127,7 @@ func Test_helm_scanner_with_dir(t *testing.T) {
require.NotNil(t, results)

failed := results.GetFailed()
assert.Equal(t, 13, len(failed))
assert.Equal(t, 15, len(failed))

visited := make(map[string]bool)
var errorCodes []string
Expand All @@ -146,7 +146,7 @@ func Test_helm_scanner_with_dir(t *testing.T) {
"AVD-KSV-0011", "AVD-KSV-0012", "AVD-KSV-0014",
"AVD-KSV-0015", "AVD-KSV-0016", "AVD-KSV-0018",
"AVD-KSV-0020", "AVD-KSV-0021", "AVD-KSV-0030",
"AVD-KSV-0104", "AVD-KSV-0106",
"AVD-KSV-0104", "AVD-KSV-0106", "AVD-KSV-0116",
}, errorCodes)
}
}
Expand Down Expand Up @@ -213,7 +213,7 @@ deny[res] {
require.NotNil(t, results)

failed := results.GetFailed()
assert.Equal(t, 15, len(failed))
assert.Equal(t, 20, len(failed))

visited := make(map[string]bool)
var errorCodes []string
Expand All @@ -233,7 +233,7 @@ deny[res] {
"AVD-KSV-0011", "AVD-KSV-0012", "AVD-KSV-0014",
"AVD-KSV-0015", "AVD-KSV-0016", "AVD-KSV-0018",
"AVD-KSV-0020", "AVD-KSV-0021", "AVD-KSV-0030",
"AVD-KSV-0104", "AVD-KSV-0106", "AVD-USR-ID001",
"AVD-KSV-0104", "AVD-KSV-0106", "AVD-KSV-0116", "AVD-USR-ID001",
}, errorCodes)
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# METADATA
# title: "No wildcard resource roles"
# description: "Check whether role permits specific verb on wildcard resources"
# title: "Manage all resources"
# description: "Full control of the cluster resources, and therefore also root on all nodes where workloads can run and has access to all pods, secrets, and data."
# scope: package
# schemas:
# - input: schema["kubernetes"]
Expand All @@ -10,8 +10,8 @@
# id: KSV046
# avd_id: AVD-KSV-0046
# severity: CRITICAL
# short_code: no-wildcard-resource-role
# recommended_action: "Create a role which does not permit specific verb on wildcard resources"
# short_code: no-wildcard-resource-clusterrole
# recommended_actions: "Remove '*' from 'rules.resources'. Provide specific list of resources to be managed by cluster role"
# input:
# selector:
# - type: kubernetes
Expand All @@ -22,7 +22,7 @@ import data.lib.utils

readVerbs := ["create", "update", "delete", "deletecollection", "impersonate", "*", "list", "get"]

readKinds := ["Role", "ClusterRole"]
readKinds := ["ClusterRole"]

resourceAllowSpecificVerbOnAnyResource[input.rules[ru]] {
some ru, r, v
Expand All @@ -33,6 +33,6 @@ resourceAllowSpecificVerbOnAnyResource[input.rules[ru]] {

deny[res] {
badRule := resourceAllowSpecificVerbOnAnyResource[_]
msg := "Role permits specific verb on wildcard resource"
msg := kubernetes.format(sprintf("%s '%s' shouldn't manage all resources", [kubernetes.kind, kubernetes.name]))
res := result.new(msg, badRule)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# METADATA
# title: "Manage all resources at the namespace"
# description: "Full control of the resources within a namespace. In some cluster configurations, this is excessive. In others, this is normal (a gitops deployment operator like flux)"
# scope: package
# schemas:
# - input: schema["kubernetes"]
# related_resources:
# - https://kubernetes.io/docs/concepts/security/rbac-good-practices/
# custom:
# id: KSV112
# avd_id: AVD-KSV-0112
# severity: CRITICAL
# short_code: no-wildcard-resource-role
# recommended_actions: "Remove '*' from 'rules.resources'. Provide specific list of resources to be managed by role in namespace"
# input:
# selector:
# - type: kubernetes
package builtin.kubernetes.KSV112

import data.lib.kubernetes
import data.lib.utils

readVerbs := ["create", "update", "delete", "deletecollection", "impersonate", "*", "list", "get"]

readKinds := ["Role"]

managingAllResourcesAtNamespace[input.rules[ru]] {
some ru, r, v
input.kind == readKinds[_]
input.rules[ru].resources[r] == "*"
input.rules[ru].verbs[v] == readVerbs[_]
}

deny[res] {
badRule := managingAllResourcesAtNamespace[_]
msg := kubernetes.format(sprintf("%s '%s' shouldn't manage all resources at the namespace '%s'", [kubernetes.kind, kubernetes.name, kubernetes.namespace]))
res := result.new(msg, badRule)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package builtin.kubernetes.KSV046
package builtin.kubernetes.KSV112

test_resource_verb_role_secrets {
r := deny with input as {
Expand Down
145 changes: 145 additions & 0 deletions rules/kubernetes/policies/general/manage_all_resources_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package builtin.kubernetes.KSV046

test_resource_verb_role_secrets {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["*"],
"verbs": ["delete"],
}],
}

count(r) > 0
}

test_resource_verb_role_pods {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["*"],
"verbs": ["deletecollection"],
}],
}

count(r) > 0
}

test_resource_verb_role_deployments {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["*"],
"verbs": ["create"],
}],
}

count(r) > 0
}

test_resource_verb_role_daemonsets {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["*"],
"verbs": ["list"],
}],
}

count(r) > 0
}

test_resource_verb_role_statefulsets {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["*"],
"verbs": ["get"],
}],
}

count(r) > 0
}

test_resource_verb_role_replicationcontrollers {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["*"],
"verbs": ["impersonate"],
}],
}

count(r) > 0
}

test_resource_resource_role_no_specific_verb {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["impersonate"],
"verbs": ["aaa"],
}],
}

count(r) == 0
}

test_resource_verb_role_no_any_verb {
r := deny with input as {
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": {
"namespace": "default",
"name": "pod-reader",
},
"rules": [{
"apiGroups": ["*"],
"resources": ["*"],
"verbs": ["*"],
}],
}

count(r) > 0
}
Loading

0 comments on commit 60ffbaf

Please sign in to comment.