Back to Cheat Sheets

🛠️ Misconfigured Cluster Components

OWASP Kubernetes Top 10 - K09

CRITICAL RISK

📋 What Is It?

Misconfigured Cluster Components is the risk that the machinery running Kubernetes itself - kube-apiserver, etcd, kube-scheduler, kube-controller-manager, every node's kubelet, kube-proxy, and add-ons - is deployed with insecure settings. The control plane is the trust root of the entire cluster: a single reachable, over-permissive component (an API server answering anonymous callers, a kubelet executing commands with no auth, an etcd reachable without a client certificate) collapses every control built above it. Unlike K01 (a bad pod) or K04 (no admission engine), K09 is about the components' own flags, ports, and certificates.

K09 OWASP Rank
Trust Root Focus Area
CIS Bench Verify With

⚠️ Common Exploits

  • Anonymous API: --anonymous-auth=true lets system:anonymous in
  • AlwaysAllow authZ: RBAC effectively switched off - every request approved
  • Legacy Insecure Port: --insecure-port=8080 - no TLS, no auth, no authz
  • Open Kubelet (10250): anonymous + AlwaysAllow exposes /exec, /run
  • Read-Only Kubelet (10255): unauthenticated pod specs, env vars, metrics
  • Exposed etcd (2379): no mTLS dumps every Secret in one command
  • Missing Admission / Audit: no NodeRestriction, PodSecurity, or audit trail

🔴 Attack Flow

1. Discover open ports (6443, 10250/10255, 2379/2380, 10257/10259)
↓
2. Probe authN/authZ - anonymous? AlwaysAllow? no etcd client cert?
↓
3. Exploit - kubelet /exec, etcd get --prefix, create a pod
↓
4. Escalate - steal SA tokens, reach cloud metadata, move node to node
↓
5. IMPACT: RCE on nodes, all Secrets exposed, full takeover!

❌ Vulnerable Code

# Bad: kube-apiserver flags that disable auth and guardrails - kube-apiserver - --anonymous-auth=true ← system:anonymous can authenticate - --authorization-mode=AlwaysAllow ← RBAC effectively OFF - --insecure-port=8080 ← legacy no-TLS, no-auth port - --insecure-bind-address=0.0.0.0 ← reachable from anywhere - --enable-admission-plugins= ← NodeRestriction/PodSecurity missing - --profiling=true ← /debug/pprof exposed # no --audit-log-path # no forensic trail # Bad: kubelet wide open - direct code execution surface authentication: { anonymous: { enabled: true } } authorization: { mode: AlwaysAllow } ← /exec for anyone on 10250 readOnlyPort: 10255 ← unauthenticated specs/env/metrics # Bad: etcd plaintext on a routable interface, no client-cert auth - etcd - --listen-client-urls=http://0.0.0.0:2379 ← anyone reaching 2379... # etcdctl --endpoints=http://HOST:2379 get / --prefix → dumps every Secret

✅ Secure Code

# Good: hardened kube-apiserver - kube-apiserver - --anonymous-auth=false - --authorization-mode=Node,RBAC ← Node + RBAC, never AlwaysAllow # legacy insecure port not set (removed in modern Kubernetes) - --enable-admission-plugins=NodeRestriction,PodSecurity - --profiling=false - --audit-log-path=/var/log/kubernetes/audit.log - --kubelet-certificate-authority=/etc/kubernetes/pki/ca.crt ← verify kubelets - --encryption-provider-config=/etc/kubernetes/enc/enc.yaml ← encrypt Secrets # Good: locked-down kubelet authentication: anonymous: { enabled: false } webhook: { enabled: true } ← authenticate via the API server x509: { clientCAFile: /etc/kubernetes/pki/ca.crt } authorization: { mode: Webhook } ← delegate authZ, never AlwaysAllow readOnlyPort: 0 ← disable the 10255 port rotateCertificates: true # Good: etcd with mutual TLS on a private interface - etcd - --client-cert-auth=true ← require client certificates - --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt - --peer-client-cert-auth=true - --listen-client-urls=https://127.0.0.1:2379,https://10.0.0.5:2379

✓ Prevention Checklist

  • API server: --anonymous-auth=false, --authorization-mode=Node,RBAC
  • No legacy insecure port or insecure bind address
  • Enable NodeRestriction and PodSecurity admission plugins
  • Kubelet: anonymous off, authorization.mode: Webhook
  • Disable the kubelet read-only port (readOnlyPort: 0)
  • etcd: require mutual TLS, private interface only
  • Encrypt Secrets at rest via EncryptionConfiguration (KMS)
  • Enable API-server audit logging with a defined policy
  • Set --profiling=false; bind component metrics to localhost
  • Rotate certificates; never ship default/self-signed certs
  • Run kube-bench (CIS Benchmark) on a schedule, fail on regression
  • Scan cluster IaC in CI (kubescape, Polaris, checkov, Trivy)

🔍 Detection & Tools

Kubernetes Tools:

kube-bench kubescape Polaris Trivy kubeaudit Falco

Guardrails:

NodeRestriction PodSecurity OPA/Gatekeeper Kyverno

How to Test:

  • kube-bench run --targets master,node,etcd,policies against the CIS Benchmark
  • Probe API anonymously: curl -sk https://TARGET:6443/api/v1/pods
  • Check kubelet: curl -sk https://NODE:10250/pods and 10255
  • Test etcd: etcdctl --endpoints=http://TARGET:2379 get / --prefix should fail
  • Gate CI on any kube-bench FAIL (JSON output + jq)

🌍 Real-World

  • Unauthenticated Dashboard / API → Cryptojacking: a control surface reachable from the internet with auth effectively disabled; automated actors schedule mining pods and reach cloud credentials - one of the most consistently reported Kubernetes incident classes.
  • Exposed etcd Disclosing Every Secret: etcd on a routable interface without client-cert auth, or a readable snapshot - one reachable datastore equals the entire cluster's credentials.
  • Open Kubelet → Node-Level Code Execution: kubelets with anonymous auth + AlwaysAllow; research tooling has repeatedly demonstrated enumerating pods then /exec against internet-exposed kubelets.

Described as recurring incident classes - no invented CVEs or statistics. The durable lesson: component misconfiguration is common on hand-built clusters, mechanically detectable with CIS tooling, and catastrophic.

📌 Quick Tips

  • DO NOT enable anonymous auth or use AlwaysAllow
  • DO NOT bind the legacy insecure port or open 10255
  • DO NOT run etcd plaintext or without encryption-at-rest
  • DO require mTLS between every component
  • DO enable NodeRestriction, PodSecurity, and audit
  • DO benchmark continuously with kube-bench (CIS)
  • DO verify the managed shared-responsibility line

📜 Related Risks

Connected OWASP Kubernetes Top 10:

  • K06 Broken Authentication - same anonymous/etcd doors
  • K01 Insecure Workloads - a bad pod vs. a bad component
  • K04 No Policy Enforcement - the admission engine
  • K05 Inadequate Logging & Monitoring - audit routing