Skip to content

Risk rules do not match role rules granting wildcard verbs or resources #529

Description

@marcinc

match_rules in config/rules.yaml select a Rule node by exact equality on resource and verb, so a role rule granting the RBAC wildcard is not matched by a risk rule naming a concrete value:

  • a role granting verbs: ['*'] on a resource is not matched by rules naming a verb (risky-create-daemonsets, risky-get-secrets, ...), even though * grants that verb
  • a role granting resources: ['*'] within an API group is not matched by rules naming a resource (risky-get-secrets, risky-any-verb-pods, ...), even though * covers that resource

This is the mirror image of #80: that issue was about a match rule being too broad (any API group satisfied it); this one is about it being too narrow.

Reproduction

Three ClusterRoles, each bound to a ServiceAccount:

# 1
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["get", "list", "delete"]
# 2
rules:
- apiGroups: ["apps"]
  resources: ["daemonsets"]
  verbs: ["*"]
# 3
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["*"]

Findings reported:

ClusterRole grants reported by not reported by
core-wildcard-reader (1) get/list/delete on every core resource, incl. secrets and pods nothing risky-get-secrets, risky-list-secrets, risky-any-resource-*
wildcard-verb-daemonsets (2) every verb on daemonsets, incl. create and update risky-any-verb-daemonsets risky-create-daemonsets, risky-update-daemonsets
wildcard-verb-secrets (3) every verb on secrets, incl. get and list risky-any-verb-secrets risky-get-secrets, risky-list-secrets

For (2) and (3) the grant is at least reported under some title, so the gap costs precision rather than coverage. For (1) nothing is reported at all: get on * resources scoped to the core group is now invisible to the report, since the fix for #80 scopes the resources: ['*'] rules to apiGroups: ['*'] (before that fix it was reported, but as "get action on all resources", which was the inaccuracy #80 objected to).

Note this only affects the risky-role template's match_rules. The subject level templates (unrestricted-cluster-wide-subjects, unrestricted-ns-level-subjects, rbac-managing-subjects) already spell the wildcard out in their queries, e.g. (r.resource = '*' OR r.url = '*') AND r.verb = '*'.

Suggested fix

Match resource and verb as alternatives including the wildcard, the way apiGroups are handled after #80 - i.e. ru0.verb IN ['create', '*'] and ru0.resource IN ['secrets', '*'] instead of the equality in the node property map.

Two things to decide before doing that, since it widens the report noticeably:

  1. Double reporting. A role granting verbs: ['*'] on secrets would then match risky-get-secrets, risky-list-secrets and risky-any-verb-secrets, so the same grant appears under three titles. The risky-any-* rules may want to become the only match for the wildcard case, or the specific rules may want to exclude a wildcard-only grant.
  2. Multi-match rules. risky-exec-pods and the risky-create-rolebinding-* rules AND several selectors together; widening each one multiplies how easily the intersection is satisfied, which is the intent but worth eyeballing against a real cluster's report first.

Found while fixing #80.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions