Cloud Security Wire
AWS Azure GCP RSS
AWSGCPAzure Hardening Guide high

Kubernetes Admission Webhook Security: Bypass Techniques and Hardening Guide

Admission webhooks are the enforcement layer for Kubernetes security policies — and misconfigurations in how they're scoped, registered, or deployed create bypass paths that let attacker workloads slip through unexamined.

By Cloud Security Wire · ·
#kubernetes#admission-webhooks#policy-enforcement#OPA#gatekeeper#kyverno#rbac#pod-security#bypass#cluster-hardening
High Severity

This issue has been assessed as high severity. Review affected configurations immediately.

Kubernetes admission webhooks are how clusters enforce security policy. OPA Gatekeeper, Kyverno, and custom ValidatingWebhookConfiguration objects intercept API server requests before they’re committed to etcd, checking them against policy rules. They’re the architectural foundation of almost every enterprise Kubernetes security posture. They’re also routinely misconfigured in ways that create complete bypass paths.

This guide covers the principal bypass techniques and the hardening controls that prevent them.

How Admission Webhooks Work

When a resource is submitted to the Kubernetes API server (a Pod, Deployment, namespace, etc.), the API server processes it through the admission control chain. ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks intercept requests matching their defined rules and forward them to an external HTTP endpoint — your policy engine. That engine evaluates the request and returns an allow/deny decision.

The key configuration object is ValidatingWebhookConfiguration:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: gatekeeper-validating-webhook-configuration
webhooks:
  - name: validation.gatekeeper.sh
    rules:
      - apiGroups: ["*"]
        apiVersions: ["*"]
        operations: ["CREATE", "UPDATE"]
        resources: ["pods", "deployments", "replicasets"]
    namespaceSelector:
      matchExpressions:
        - key: admission.gatekeeper.sh/ignore
          operator: DoesNotExist
    failurePolicy: Fail
    clientConfig:
      service:
        name: gatekeeper-webhook-service
        namespace: gatekeeper-system
        port: 443

Every field in this configuration is a potential bypass surface.

Bypass Technique 1: Namespace Label Manipulation

The most common misconfiguration is a namespaceSelector that allows labels on namespaces to opt out of webhook evaluation. The Gatekeeper default configuration uses a selector that skips namespaces with the label admission.gatekeeper.sh/ignore. If an attacker has RBAC permissions to label namespaces, they can label a target namespace to exclude it from policy enforcement, then deploy workloads without restriction.

Exploit path:

# Attacker has namespace edit permissions
kubectl label namespace target-namespace admission.gatekeeper.sh/ignore=true

# Now deploy a privileged container — policy engine skips this namespace
kubectl -n target-namespace run bypass \
  --image=ubuntu \
  --privileged=true \
  --overrides='{"spec":{"hostPID":true,"containers":[{"name":"bypass","image":"ubuntu","securityContext":{"privileged":true}}]}}'

Fix: Lock namespace labels. Use RBAC to prevent non-admin users from labelling namespaces. For Gatekeeper, consider using objectSelector or removing the opt-out label mechanism entirely in production clusters.

Check for exposure:

# Identify namespaces that bypass webhook evaluation
kubectl get namespaces -l admission.gatekeeper.sh/ignore --no-headers | awk '{print $1}'

Bypass Technique 2: Unscoped Resource Coverage

Webhooks define which API groups, resources, and operations they intercept. A common error is defining coverage for pods but forgetting that pod-creating resources like CronJob, StatefulSet, and custom CRDs also create pods. Policies that only evaluate Pod objects are bypassed by creating a Deployment or Job that spawns the restricted pod.

The more complete resource list for pod policy enforcement:

rules:
  - apiGroups: ["", "apps", "batch"]
    apiVersions: ["*"]
    operations: ["CREATE", "UPDATE"]
    resources:
      - pods
      - deployments
      - replicasets
      - statefulsets
      - daemonsets
      - jobs
      - cronjobs
      - replicationcontrollers

Audit your webhook coverage:

kubectl get validatingwebhookconfigurations -o json \
  | jq '.items[].webhooks[] | {name: .name, resources: .rules[].resources}'

If cronjobs or statefulsets are missing from the resource list, those are bypass vectors.

Bypass Technique 3: failurePolicy: Ignore

When the webhook endpoint is unreachable — due to a crash, network partition, or resource starvation — the failurePolicy field determines what happens. Fail blocks the request. Ignore allows it through.

A common compromise path: overwhelm or crash the webhook service pod to force Ignore failurePolicy into effect, then deploy restricted workloads during the window when the policy engine is down.

Audit your failurePolicy:

kubectl get validatingwebhookconfigurations -o json \
  | jq '.items[].webhooks[] | {name: .name, failurePolicy: .failurePolicy}'

Any webhook using failurePolicy: Ignore is a bypass risk in a denial-of-service scenario. Policy engines like Gatekeeper and Kyverno should be deployed with Fail in production.

Protect the webhook service from DoS:

# Resource limits for Gatekeeper controller
resources:
  limits:
    cpu: 1000m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 256Mi

Set a PodDisruptionBudget for the webhook controller and deploy it across multiple nodes with anti-affinity rules.

Bypass Technique 4: RBAC Access to Webhook Configuration Objects

If an attacker gains access to a ServiceAccount with update or delete permissions on ValidatingWebhookConfiguration objects, they can disable the enforcement layer directly.

# Attacker modifies webhook to allow all
kubectl patch validatingwebhookconfiguration gatekeeper-validating-webhook-configuration \
  --type='json' \
  -p='[{"op":"replace","path":"/webhooks/0/failurePolicy","value":"Ignore"}]'

# Or delete it entirely
kubectl delete validatingwebhookconfiguration gatekeeper-validating-webhook-configuration

Protect webhook configuration objects with RBAC:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: deny-webhook-mutation
rules:
  - apiGroups: ["admissionregistration.k8s.io"]
    resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"]
    verbs: ["delete", "update", "patch"]
    # Leave this empty to deny for non-privileged roles

Audit which principals have write access to these objects:

kubectl auth can-i update validatingwebhookconfigurations \
  --as=system:serviceaccount:default:my-serviceaccount

Bypass Technique 5: DryRun Requests

Kubernetes admission webhooks receive a dryRun flag on requests. Webhooks that fail to handle dryRun correctly may pass requests in dryRun mode but reject them otherwise — the inverse of the intended behaviour. Less commonly, some custom webhooks reject dryRun operations without enforcing policy on live operations.

Always check dryRun handling:

kubectl apply --dry-run=server -f privileged-pod.yaml

If a dry-run passes a policy check that a live apply would block, your webhook is correctly enforcing — the dryRun test confirms policy is active. If the inverse is true, audit your webhook code for incorrect dryRun handling.

Audit Your Cluster’s Webhook Posture

# List all admission webhooks
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations

# Check namespace selectors
kubectl get validatingwebhookconfigurations -o json \
  | jq '.items[].webhooks[] | {name: .name, namespaceSelector: .namespaceSelector}'

# Verify TLS is enforced
kubectl get validatingwebhookconfigurations -o json \
  | jq '.items[].webhooks[].clientConfig'

Key Hardening Checklist

  • failurePolicy: Fail on all production webhooks
  • No opt-out namespace labels in production without explicit audit trail
  • All pod-creating resource types covered (Deployment, StatefulSet, Job, CronJob, DaemonSet)
  • RBAC preventing non-admin write access to validatingwebhookconfigurations
  • Webhook service deployed with resource limits and PodDisruptionBudget
  • Webhook service TLS certificate rotation automated
  • Alert on deletion or modification of ValidatingWebhookConfiguration objects

Admission webhooks are only effective if they’re correctly scoped, resilient to failure, and protected from modification. Audit each of these surfaces regularly — they’re the first thing a container escape or privilege escalation attempt will try to sidestep.

← All Analysis Subscribe via RSS