Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update rego title in OSS defsec Part2 #1386

Merged
merged 4 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/


16 changes: 8 additions & 8 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, 19, len(failed))

visited := make(map[string]bool)
var errorCodes []string
Expand All @@ -58,7 +58,7 @@ func Test_helm_scanner_with_archive(t *testing.T) {
errorCodes = append(errorCodes, id)
}
}
assert.Len(t, errorCodes, 13)
assert.Len(t, errorCodes, 14)

sort.Strings(errorCodes)

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-0104", "AVD-KSV-0106", "AVD-KSV-0116",
}, 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, 16, 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, 21, len(failed))

visited := make(map[string]bool)
var errorCodes []string
Expand All @@ -224,7 +224,7 @@ deny[res] {
errorCodes = append(errorCodes, id)
}
}
assert.Len(t, errorCodes, 14)
assert.Len(t, errorCodes, 15)

sort.Strings(errorCodes)

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