Kubernetes ValidatingWebhookConfiguration
The original author of this page is Guillaume
Definition
ValidatingWebhookConfiguration is a Kubernetes resource that registers one or more validating admission webhooks. These webhooks receive AdmissionReview requests from the API server after authentication and authorization, but before the object is persisted.[3][10]
Validating webhooks can reject a request. Mutating webhooks, configured with MutatingWebhookConfiguration, can change the object first. Security reviews should usually inspect both resources because a malicious or weak mutating webhook can rewrite workloads, while a validating webhook or policy engine can block or allow them.[3]
Purpose
The purpose of a ValidatingWebhookConfiguration is to define when the API server should call a validating webhook and how it should handle the webhook result.[3][8] The important security question is not only "is a policy installed?", but also:
- Which API groups, resources, operations, and scopes does it match?[8]
- Which namespaces or objects are excluded by selectors?[8]
- Does
matchConditionsskip any request classes?[7][8] - Does
failurePolicyfail open withIgnoreor fail closed withFail?[3][8] - Is the webhook service reachable, trusted by the configured
caBundle, and run by a highly privileged service account? - Does the policy engine also expose exception resources, excluded users, or excluded groups?
Example
Here is an example of a ValidatingWebhookConfiguration:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: example-validation-webhook
webhooks:
- name: pods.example.local
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Fail
timeoutSeconds: 5
clientConfig:
service:
namespace: webhook-system
name: example-validation-webhook
path: /validate
caBundle: <base64-ca-bundle>
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
scope: "Namespaced"
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values: ["kube-system"]
The example uses the v1 webhook fields for request matching, service/CA transport, failure handling, and dry-run semantics.[3][8]
The main difference between a ValidatingWebhookConfiguration and policies :

Kyverno.png
- ValidatingWebhookConfiguration (VWC) : A Kubernetes resource that defines a validating webhook, which is a server-side component that validates incoming Kubernetes API requests against a set of predefined rules and constraints.[8]
- Kyverno ClusterPolicy: A policy definition that specifies a set of rules and constraints for validating and enforcing Kubernetes resources, such as pods, deployments, and services.[13]
Enumeration
$ kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations
$ kubectl get validatingwebhookconfiguration <name> -o yaml
$ kubectl get mutatingwebhookconfiguration <name> -o yaml
$ kubectl get svc,deploy,pod -A | grep -i webhook
List both webhook configuration kinds and inspect their YAML plus the referenced service or URL:[3][4]
Fields to inspect:
rules: Check covered API groups, versions, resources, subresources, operations, and scope.[8]namespaceSelector/objectSelector: Look for namespaces or labels that exclude resources from policy.[8]matchConditions: CEL expressions can intentionally or accidentally skip requests.[7][8]failurePolicy:Ignorelets requests continue if the webhook fails;Failblocks them.[3][8]sideEffects: Webhooks with side effects may not support dry-run testing.[3]timeoutSeconds: Very short timeouts combined withIgnorecan become fail-open behavior.[3][4]clientConfig: Review whether the webhook points to an in-cluster Service or external URL.[3] Inspect the backing workload and service account.reinvocationPolicy: Mutating webhooks may be reinvoked when later mutation changes the object.[3]
Native CEL admission policies
Modern clusters can also enforce admission logic with native policy objects in admissionregistration.k8s.io, not only with webhook configurations. ValidatingAdmissionPolicy is an in-process CEL-based alternative to validating webhooks.[5][7] It is only active when a ValidatingAdmissionPolicyBinding selects it.[5] MutatingAdmissionPolicy is stable in Kubernetes v1.36.[6] It is activated by MutatingAdmissionPolicyBinding for CEL-generated mutations.[6]
Enumerate them with:
kubectl api-resources --api-group=admissionregistration.k8s.io -o wide
kubectl get validatingadmissionpolicies,validatingadmissionpolicybindings
kubectl get mutatingadmissionpolicies,mutatingadmissionpolicybindings 2>/dev/null || true
kubectl get validatingadmissionpolicy <name> -o yaml
kubectl get validatingadmissionpolicybinding <name> -o yaml
Inspect policies together with their bindings because the binding supplies the scope and enforcement behavior.[5][6]
Security checks:
- A policy without a binding does not enforce anything.[5][6]
validationActionson the binding decides whether validation failures are denied, warned, audited, or only recorded.[5]failurePolicy: Ignorelets CEL evaluation errors or misconfiguration fail open.[5]matchConstraints,matchConditions,namespaceSelector, andobjectSelectorcan exclude sensitive requests.[5][7]paramKindandparamRefcan make ConfigMaps or CRD-backed parameter objects part of the policy boundary; check who can modify those parameter objects.[5][6]- Writes to policies, bindings, and parameter resources should be treated like privileged admission-control changes.[4][5]
Abusing Kyverno and Gatekeeper VWC
As a practical check, policy operators commonly install one or more ValidatingWebhookConfiguration objects; verify the actual objects rather than assuming every installation does so.[11][12]
Kyverno and Gatekeeper are both Kubernetes policy engines that provide a framework for defining and enforcing policies across a cluster.[1][2]
Exceptions refer to specific rules or conditions that allow a policy to be bypassed or modified under certain circumstances but this is not the only way![12][13]
For Kyverno, the resource webhook configuration kyverno-resource-validating-webhook-cfg is populated from policies that match resources.[11]
For Gatekeeper, the default validating webhook configuration is gatekeeper-validating-webhook-configuration.[12]
Both come with defaults, but administrator teams might update those two configurations.[11][12]
Use Case
$ kubectl get validatingwebhookconfiguration kyverno-resource-validating-webhook-cfg -o yaml
Now, identify the following output :
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- default
- TEST
- YOYO
- kube-system
- MYAPP
Here, kubernetes.io/metadata.name is an immutable namespace label whose value is the namespace name. Namespaces with names in the values list will be excluded from the webhook's match set.[8][9]
Check namespaces existence. Sometimes, due to automation or misconfiguration, some namespaces might have not been created. If you have permission to create a namespace, you could create a namespace with a name in the values list and this webhook's policies won't apply to workloads in that namespace.[8]
The goal of this attack is to exploit misconfiguration inside VWC in order to bypass operators restrictions and then elevate your privileges with other techniques
Other common bypass or abuse patterns:
- An
objectSelectorthat allows users to add an opt-out label to their own objects.[8] failurePolicy: Ignoreon security-critical validation, especially when the webhook Service has no endpoints or unreliable networking.[3][4]- Policy engine exceptions for users, groups, service accounts, namespaces, or roles that are broader than intended.[12][13][14]
- Missing coverage for workload controller templates,
pods/ephemeralcontainers,pods/exec, custom resources, or update operations.[4][8] - Write access to
validatingwebhookconfigurations,mutatingwebhookconfigurations, Gatekeeper constraints, Kyverno policies, or exception resources.[4][5] - A malicious mutating webhook that injects containers, changes images, mounts secrets, adds tolerations, or changes service account selection before validation.[3]
Remember that admission only protects requests that pass through the API server admission chain. Static Pods, node-local runtime socket access, direct kubelet abuse, and direct etcd access are different trust paths and need separate hardening and monitoring.
Abusing Roles/ClusterRoles in Kubernetes
References
- [1] Open Policy Agent Gatekeeper
- [2] Kyverno
- [3] Dynamic Admission Control | Kubernetes
- [4] Admission Webhook Good Practices | Kubernetes
- [5] Validating Admission Policy | Kubernetes
- [6] Mutating Admission Policy | Kubernetes
- [7] Common Expression Language in Kubernetes
- [8] ValidatingWebhookConfiguration | Kubernetes
- [9] Namespaces | Kubernetes
- [10] Controlling Access to the Kubernetes API | Kubernetes
- [11] Kubernetes Admission Controllers | Kyverno
- [12] Exempting Namespaces from the Gatekeeper Admission Webhook
- [13] ClusterPolicy Overview | Kyverno
- [14] Validate Rules | Kyverno
[!TIP] Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Browse the full HackTricks Training catalog.Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.


