Back to Checks
kubernetes

User or group does not have create, update, or delete permissions on webhook configurations

rbac_minimize_webhook_config_access
Service: rbacSeverity: high
OfficialBuilt-inVerified
Categories:identity-accesscluster-security
Resource Type:ClusterRoleBinding

User or group RBAC assignments that grant privileges to create, update, or delete validatingwebhookconfigurations and mutatingwebhookconfigurations are identified.

Focus is on permissions that allow modifying admission webhook configuration objects.

Risk

Excess rights over admission webhooks allow reading or mutating all admitted API objects, undermining confidentiality and integrity.

An attacker could inject privileged mutations, bypass policy, or block admissions, leading to privilege escalation and cluster-wide denial of service.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler kubernetes --checks rbac_minimize_webhook_config_access

Recommendation

  • Enforce least privilege; limit webhook config create, update, delete to a small, trusted admin group.
  • Avoid wildcard resources/verbs and use separation of duties with change approval.
  • Monitor changes via audit logging to provide defense in depth.

Remediation

CLI

kubectl delete clusterrolebinding <example_resource_name>

Other

1Identify the ClusterRoleBinding that assigns a User or Group to a ClusterRole with create, update, or delete on validatingwebhookconfigurations or mutatingwebhookconfigurations (e.g., kubectl get clusterrolebindings).
2Delete that ClusterRoleBinding, or edit the bound ClusterRole to remove any rules granting those verbs on these resources.
3Save/apply the change; no restart is required.

Check Code

from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.rbac.lib.role_permissions import (
    is_rule_allowing_permissions,
)
from prowler.providers.kubernetes.services.rbac.rbac_client import rbac_client

resources = [
    "validatingwebhookconfigurations",
    "mutatingwebhookconfigurations",
]
verbs = ["create", "update", "delete"]
api_groups = ["admissionregistration.k8s.io"]


class rbac_minimize_webhook_config_access(Check):
    def execute(self) -> Check_Report_Kubernetes:
        findings = []
        # Collect unique subjects and the ClusterRole names bound to them
        subjects_bound_roles = {}
        for crb in rbac_client.cluster_role_bindings.values():
            for subject in crb.subjects:
                # CIS benchmarks scope these checks to human identities only
                if subject.kind in ["User", "Group"]:
                    key = (subject.kind, subject.name, subject.namespace)
                    if key not in subjects_bound_roles:
                        subjects_bound_roles[key] = (subject, set())
                    subjects_bound_roles[key][1].add(crb.roleRef.name)

        cluster_roles_by_name = {
            cr.metadata.name: cr for cr in rbac_client.cluster_roles.values()
        }
        for _, (subject, role_names) in subjects_bound_roles.items():
            report = Check_Report_Kubernetes(metadata=self.metadata(), resource=subject)
            report.resource_name = f"{subject.kind}:{subject.name}"
            report.resource_id = f"{subject.kind}/{subject.name}"
            report.status = "PASS"
            report.status_extended = f"User or group '{subject.name}' does not have access to create, update, or delete webhook configurations."
            for role_name in role_names:
                cr = cluster_roles_by_name.get(role_name)
                if cr and is_rule_allowing_permissions(
                    cr.rules, resources, verbs, api_groups
                ):
                    report.status = "FAIL"
                    report.status_extended = f"User or group '{subject.name}' has access to create, update, or delete webhook configurations."
                    break
            findings.append(report)

        return findings