Skip to content

Commit

Permalink
FWI-2719: Enable new RBAC / sensitive content / Pod exec checks, add …
Browse files Browse the repository at this point in the history
…`hasPrefix` and `hasSuffix` functions to the GO template, exempt `system:` name prefixes for RBAC checks, sensitive content checks ignore `valueFrom`, (#832)

* Enable these checks in the default configuration file, which may produce many new results:
  * automountServiceAccountToken
  * linuxHardening
  * sensitiveConfigmapContent and sensitiveContainerEnvVar
  * clusterrolebindingClusterAdmin, rolebindingClusterAdminClusterRole, and rolebindingClusterAdminRole
  * clusterrolePodExecAttach, rolePodExecAttach, clusterrolebindingPodExecAttach, rolebindingClusterRolePodExecAttach, and  rolebindingRolePodExecAttach
* Ignore the `missingNetworkPolicy` and `automountServiceAccountToken` checks by default
* `hasPrefix` and `hasSuffix` functions are now available in the go template
* Fix the `sensitiveContainerEnvVar` check to ignore sensitive environment
variable names when those variables use `valueFrom` to reference an
external resource.
* Add the `*ClusterAdmin` checks to `examples/config-full.yaml`.
* Exempt the prefix `system:` instead of individual entries for RBAC checks (#871)
  • Loading branch information
ivanfetch-wt authored Nov 14, 2022
1 parent 4091355 commit 467d06f
Show file tree
Hide file tree
Showing 36 changed files with 854 additions and 77 deletions.
5 changes: 2 additions & 3 deletions checks/clusterrolePodExecAttach.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ schemaString: |
- const: 'admin'
- const: "cluster-admin"
- const: "edit"
- const: "system:aggregate-to-edit"
- const: "system:controller:generic-garbage-collector"
- const: "system:controller:namespace-controller"
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- properties:
rules:
type: array
Expand Down
6 changes: 3 additions & 3 deletions checks/clusterrolebindingClusterAdmin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ schemaString: |
type: string
anyOf:
- const: "cluster-admin"
- const: "system:controller:generic-garbage-collector"
- const: "system:controller:namespace-controller"
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- required: ["roleRef"]
properties:
roleRef:
Expand All @@ -39,7 +39,7 @@ additionalSchemaStrings:
rbac.authorization.k8s.io/ClusterRole: |
type: object
# Do not alert on default ClusterRoleBindings.
{{ if and (ne .metadata.name "cluster-admin") (ne .metadata.name "system:controller:generic-garbage-collector") (ne .metadata.name "system:controller:namespace-controller") }}
{{ if and (ne .metadata.name "cluster-admin") (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }}
required: ["metadata", "rules"]
allOf:
- properties:
Expand Down
6 changes: 3 additions & 3 deletions checks/clusterrolebindingPodExecAttach.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ schemaString: |
type: string
anyOf:
- const: "cluster-admin"
- const: "system:controller:generic-garbage-collector"
- const: "system:controller:namespace-controller"
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- required: ["roleRef"]
properties:
roleRef:
Expand All @@ -37,7 +37,7 @@ additionalSchemaStrings:
rbac.authorization.k8s.io/ClusterRole: |
type: object
# Do not alert on default ClusterRoleBindings.
{{ if and (ne .metadata.name "cluster-admin") (ne .metadata.name "system:controller:generic-garbage-collector") (ne .metadata.name "system:controller:namespace-controller") }}
{{ if and (ne .metadata.name "cluster-admin") (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }}
required: ["metadata", "rules"]
allOf:
- properties:
Expand Down
83 changes: 47 additions & 36 deletions checks/rolePodExecAttach.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,51 @@ schemaString: |
'$schema': http://json-schema.org/draft-07/schema
type: object
required: ["metadata", "rules"]
properties:
metadata:
required: ["name"]
properties:
name:
type: string
rules:
type: array
items:
type: object
not:
required: ["apiGroups", "resources", "verbs"]
anyOf:
# Do not alert on default Roles.
- properties:
metadata:
required: ["name"]
properties:
apiGroups:
type: array
contains:
type: string
anyOf:
- const: ""
- const: '*'
resources:
type: array
contains:
type: string
anyOf:
- const: '*'
- const: "pods/exec"
- const: "pods/attach"
verbs:
type: array
contains:
type: string
anyOf:
- const: '*'
# An exec is also possible by `get`ing a web socket.
- const: 'get'
- const: 'create'
name:
type: string
anyOf:
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- properties:
metadata:
required: ["name"]
properties:
name:
type: string
rules:
type: array
items:
type: object
not:
required: ["apiGroups", "resources", "verbs"]
properties:
apiGroups:
type: array
contains:
type: string
anyOf:
- const: ""
- const: '*'
resources:
type: array
contains:
type: string
anyOf:
- const: '*'
- const: "pods/exec"
- const: "pods/attach"
verbs:
type: array
contains:
type: string
anyOf:
- const: '*'
# An exec is also possible by `get`ing a web socket.
- const: 'get'
- const: 'create'
14 changes: 14 additions & 0 deletions checks/rolebindingClusterAdminClusterRole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ schemaString: |
kind:
type: string
const: "Role"
# Do not alert on default ClusterRoleBindings.
- required: ["metadata"]
properties:
metadata:
type: object
required: ["name"]
properties:
name:
type: string
anyOf:
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- required: ["roleRef"]
properties:
roleRef:
Expand All @@ -36,6 +48,7 @@ additionalSchemaStrings:
type: object
# This schema is validated for all roleBindings, regardless of their roleRef.
{{ if eq .roleRef.kind "ClusterRole" }}
{{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }}
required: ["metadata", "rules"]
allOf:
- properties:
Expand Down Expand Up @@ -82,3 +95,4 @@ additionalSchemaStrings:
- "patch"
- "delete"
{{ end }}
{{ end }}
14 changes: 14 additions & 0 deletions checks/rolebindingClusterAdminRole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ schemaString: |
kind:
type: string
const: "ClusterRole"
# Do not alert on default RoleBindings.
- required: ["metadata"]
properties:
metadata:
type: object
required: ["name"]
properties:
name:
type: string
anyOf:
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- required: ["roleRef"]
properties:
roleRef:
Expand All @@ -34,6 +46,7 @@ additionalSchemaStrings:
type: object
# This schema is validated for all roleBindings, regardless of their roleRef.
{{ if eq .roleRef.kind "Role" }}
{{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }}
required: ["metadata", "rules"]
allOf:
- properties:
Expand Down Expand Up @@ -80,3 +93,4 @@ additionalSchemaStrings:
- "patch"
- "delete"
{{ end }}
{{ end }}
14 changes: 14 additions & 0 deletions checks/rolebindingClusterRolePodExecAttach.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ schemaString: |
kind:
type: string
const: "Role"
# Do not alert on default RoleBindings.
- required: ["metadata"]
properties:
metadata:
type: object
required: ["name"]
properties:
name:
type: string
anyOf:
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- required: ["roleRef"]
properties:
roleRef:
Expand All @@ -34,6 +46,7 @@ additionalSchemaStrings:
type: object
# This schema is validated for all roleBindings, regardless of their roleRef.
{{ if eq .roleRef.kind "ClusterRole" }}
{{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }}
required: ["metadata", "rules"]
allOf:
- properties:
Expand Down Expand Up @@ -76,3 +89,4 @@ additionalSchemaStrings:
- const: 'get'
- const: 'create'
{{ end }}
{{ end }}
14 changes: 14 additions & 0 deletions checks/rolebindingRolePodExecAttach.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ schemaString: |
kind:
type: string
const: "Role"
# Do not alert on default RoleBindings.
- required: ["metadata"]
properties:
metadata:
type: object
required: ["name"]
properties:
name:
type: string
anyOf:
- pattern: '^system:'
- const: "gce:podsecuritypolicy:calico-sa"
- required: ["roleRef"]
properties:
roleRef:
Expand All @@ -37,6 +49,7 @@ additionalSchemaStrings:
type: object
# This schema is validated for all roleBindings, regardless of their roleRef.
{{ if eq .roleRef.kind "Role" }}
{{ if and (not (hasPrefix .metadata.name "system:")) (ne .metadata.name "gce:podsecuritypolicy:calico-sa") }}
required: ["metadata", "rules"]
allOf:
- properties:
Expand Down Expand Up @@ -79,3 +92,4 @@ additionalSchemaStrings:
- const: 'get'
- const: 'create'
{{ end }}
{{ end }}
69 changes: 38 additions & 31 deletions checks/sensitiveContainerEnvVar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,41 @@ schemaString: |
type: array
items:
type: object
required: ["name"]
properties:
name:
type: string
'$comment': These environment variable names will be disallowed.
allOf:
- not:
pattern: '(?i)^AWS_SECRET_ACCESS_KEY$'
- not:
pattern: '(?i)^GOOGLE_APPLICATION_CREDENTIALS$'
- not:
pattern: '(?i)^AZURE_.+KEY$'
- not:
pattern: '(?i)^OCI_CLI_KEY_CONTENT$'
- not:
pattern: '(?i)password'
- not:
pattern: '(?i)token'
- not:
pattern: '(?i)bearer'
- not:
pattern: '(?i)secret'
'$comment': This allows variable names not excluded above.
- pattern: '(?i).*'
value:
type: string
'$comment': These environment variable values will be disallowed.
allOf:
- not:
'$comment': THis matches variations like begin private key, begin rsa private key ...
pattern: '(?i)\s*-BEGIN\s+.*PRIVATE KEY-\s*'
oneOf:
- required: ["name", "value"]
properties:
name:
type: string
'$comment': These environment variable names will be disallowed.
allOf:
- not:
pattern: '(?i)^AWS_SECRET_ACCESS_KEY$'
- not:
pattern: '(?i)^GOOGLE_APPLICATION_CREDENTIALS$'
- not:
pattern: '(?i)^AZURE_.+KEY$'
- not:
pattern: '(?i)^OCI_CLI_KEY_CONTENT$'
- not:
pattern: '(?i)password'
- not:
pattern: '(?i)token'
- not:
pattern: '(?i)bearer'
- not:
pattern: '(?i)secret'
'$comment': This allows variable names not excluded above.
- pattern: '(?i).*'
value:
type: string
'$comment': These environment variable values will be disallowed.
allOf:
- not:
'$comment': THis matches variations like begin private key, begin rsa private key ...
pattern: '(?i)\s*-BEGIN\s+.*PRIVATE KEY-\s*'
- required: ["name", "valueFrom"]
properties:
name:
type: string
valueFrom:
type: object
12 changes: 12 additions & 0 deletions docs/customization/custom-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,18 @@ schemaString: |
{{ end }}
```

### Additional Go Template Functions

These functions are also available in the GO template.

* [hasPrefix](https://pkg.go.dev/strings#HasPrefix) - for example, `hasPrefix "string" "prefix"`
* [hasSuffix](https://pkg.go.dev/strings#HasSuffix) - for example, `hasSuffix "string" "suffix"`

For example, the `hasPrefix` function can be used in a template to determine whether a resource name starts with `system:`
```
{{ if hasPrefix .metadata.name "system:" }}
```
## Multi-Resource Checks
You can write checks that span multiple resources. This is helpful for ensuring e.g.
that every Deployment has a PDB or an HPA associated with it.
Expand Down
3 changes: 3 additions & 0 deletions examples/config-full.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ checks:
clusterrolebindingPodExecAttach: danger
rolebindingClusterRolePodExecAttach: danger
rolebindingRolePodExecAttach: danger
clusterrolebindingClusterAdmin: danger
rolebindingClusterAdminClusterRole: danger
rolebindingClusterAdminRole: danger
# custom
resourceLimits: warning
imageRegistry: danger
Expand Down
Loading

0 comments on commit 467d06f

Please sign in to comment.