Back

K09: Misconfigured Cluster Components - Overview

What is Misconfigured Cluster Components?

Misconfigured Cluster Components is the risk that the machinery running Kubernetes itself—the control-plane and node processes—is deployed with insecure settings. Every cluster is held up by a small set of long-running components: the kube-apiserver, etcd, the kube-scheduler, the kube-controller-manager, and on every node the kubelet, kube-proxy, the container runtime, and cluster add-ons such as CoreDNS. Each one exposes flags, ports, certificates, and authorization modes. When those knobs are left at insecure values, an attacker does not need to break your applications—the platform hands them the keys.

This is K09 in the OWASP Kubernetes Top 10. It is distinct from a single bad pod (that is K01 — Insecure Workload Configurations) and from the absence of an admission policy engine (that is K04 — Lack of Centralized Policy Enforcement). K09 is about the components themselves: an API server that answers anonymous callers, a kubelet that executes commands with no authentication, or an etcd database reachable without a client certificate. These are the foundations. If they are weak, no workload policy above them can save you.

Core Concept

A Kubernetes cluster is a set of trusted components talking over the network:

  kubectl / clients
        |
        v
  kube-apiserver  <--- the single front door; authN + authZ + admission
        |                      |
        v                      v
      etcd                  kubelet (every node)  ---> container runtime
   (all cluster                 |
    state + Secrets)            v
                             pods / workloads

  Also present: kube-scheduler, kube-controller-manager,
                kube-proxy, CoreDNS, cloud-controller-manager

K09 asks a simple question about each of these:
  "Does it require authentication? Does it authorize? Is its traffic
   encrypted with mutual TLS? Are its debug/metrics ports locked down?"

Secure component:            Misconfigured component:
  authN required               --anonymous-auth=true
  authZ = Node,RBAC            --authorization-mode=AlwaysAllow
  mTLS everywhere              plaintext / no client cert (etcd, kubelet)
  no legacy insecure port      --insecure-port still bound
  audit enabled                audit disabled, no record of access
  metrics/debug protected      /metrics, pprof, 10255 open to anyone

The theme of K09 is authentication and authorization on the infrastructure itself. Kubernetes ships hardened defaults in modern versions, but clusters that are hand-rolled, upgraded from old versions, or built from copy-pasted flags routinely reintroduce the insecure settings that the project spent years removing.

The Components and Their Dangerous Knobs

ComponentRoleSignature misconfiguration
kube-apiserverThe one front door; authenticates, authorizes, admits every request--anonymous-auth=true, --authorization-mode=AlwaysAllow, legacy insecure port, disabled admission plugins
etcdStores all cluster state, including every Secret, in plaintext keysNo client-cert (mTLS) auth, bound to a routable interface, no encryption-at-rest
kubeletNode agent; runs and manages containers, exposes exec/logs--anonymous-auth=true, --authorization-mode=AlwaysAllow, read-only port 10255, open 10250
kube-controller-managerRuns controllers; signs service-account tokens and certs--use-service-account-credentials=false, weak --service-account-private-key handling, profiling open
kube-schedulerAssigns pods to nodesBind on all interfaces, profiling/pprof exposed, no auth on metrics
kube-proxyPrograms node networkingOverly broad kubeconfig, metrics bound to 0.0.0.0
CoreDNS / add-onsCluster DNS and other servicesOver-permissive RBAC for the add-on, exposed metrics/health

Why Does This Matter?

The control plane is not one more workload—it is the trust root of the entire cluster. A single reachable, over-permissive component collapses every other control you have built above it.

Business Impact

Technical Impact

Technical Context

1. API Server Misconfiguration

The kube-apiserver is the only component clients talk to directly, so its flags matter most. The dangerous ones:

# DANGEROUS API-server flags
--anonymous-auth=true                 # lets system:anonymous authenticate
--authorization-mode=AlwaysAllow      # every authenticated request is approved
--insecure-port=8080                  # legacy plaintext, no-auth port (removed in modern K8s)
--insecure-bind-address=0.0.0.0       # that port reachable from anywhere
--enable-admission-plugins=            # NodeRestriction / PodSecurity omitted
--profiling=true                      # /debug/pprof exposed
--audit-log-path=                     # empty: no audit trail
--tls-min-version=VersionTLS10        # weak transport
--kubelet-certificate-authority=      # unset: API server won't verify kubelets

Historically, the --insecure-port (default 8080) served the API with no authentication and no authorization at all. Anyone who could reach it was effectively cluster-admin. The flag was deprecated and finally removed, but old clusters, lab guides, and copied manifests still carry it.

2. Kubelet Misconfiguration

Every node runs a kubelet that manages containers and exposes an HTTP API. It has its own authentication and authorization, separate from the API server, and its defaults on hand-built clusters are frequently wrong.

# DANGEROUS kubelet settings
authentication:
  anonymous:
    enabled: true          # anonymous callers accepted on 10250
authorization:
  mode: AlwaysAllow        # no authorization check at all
readOnlyPort: 10255        # unauthenticated read-only API (pods, specs, env)

# Port 10250 = full kubelet API: /exec /run /attach /logs
# Port 10255 = read-only: /pods /metrics /spec  (no auth by design)

An open 10250 with anonymous auth and AlwaysAllow is one of the most direct paths to code execution in all of Kubernetes: list pods via the API, then call /exec on a chosen container.

3. etcd Misconfiguration

etcd is the cluster's database. Everything—objects, ConfigMaps, and Secrets—lives there, and by default Secrets are stored un-encrypted (base64 is not encryption). Two failures dominate:

# DANGEROUS etcd exposure
--listen-client-urls=http://0.0.0.0:2379   # plaintext, routable
# (no --client-cert-auth, no --trusted-ca-file)

# Anyone who reaches 2379 can read every key:
etcdctl --endpoints=http://TARGET:2379 get / --prefix --keys-only
etcdctl --endpoints=http://TARGET:2379 get /registry/secrets/default/db --print-value-only

# Missing encryption-at-rest: Secrets sit in etcd in the clear
# (no EncryptionConfiguration passed to the API server)

etcd should be reachable only from the API server, over mutual TLS, on a private interface—and Secrets should be encrypted at rest so a stolen etcd snapshot is not a full breach.

4. Admission Controller Set

Admission controllers are compiled into the API server and enabled with --enable-admission-plugins. Two are security-critical:

Turning these off, or running with an empty admission set, removes guardrails the rest of your security model assumes are present.

5. Disabled Audit, Weak Certs, Exposed Metrics/Debug

# Audit disabled: no record of who did what
--audit-log-path unset  ->  breaches leave no trail

# Self-signed / default / long-lived certificates
# never rotated  ->  a leaked key is valid indefinitely

# Component debug + metrics exposed without auth
GET http://node:10255/metrics          # kubelet read-only metrics
GET http://apiserver:6443/debug/pprof/ # profiling if --profiling=true
GET http://scheduler:10259/metrics     # scheduler metrics on all interfaces

Where the Misconfigurations Come From

SourceWhy it goes wrong
Hand-rolled / "the hard way" clustersEvery flag is set manually; one wrong value ships silently
Old clusters upgraded in placeInsecure legacy flags (insecure-port, AlwaysAllow) survive upgrades
Copy-pasted manifests and tutorialsLab-grade settings (anonymous auth, no TLS) reach production
Cloud/provider defaults not verifiedManaged clusters are safer, but add-ons and node config still drift
Convenience during debuggingSomeone opens a port or loosens auth "temporarily" and never reverts

Real-World Impact

The incidents below are described as classes of incident repeatedly observed and documented by the security community. Specific version numbers and statistics are intentionally omitted; the durable lesson is in the pattern, not a headline figure.

Case Class 1: Unauthenticated Kubernetes Dashboard / API Leading to Cryptojacking

Misconfiguration: A control-plane surface—an administrative dashboard or an API server—was reachable from the internet with authentication effectively disabled (anonymous access or no login).

Impact: Automated actors discovered the open surface, scheduled cryptomining pods, and in several documented cases reached cloud credentials available from within the environment, pivoting beyond the cluster. This class of exposure—an open management plane—is one of the most consistently reported Kubernetes incidents.

Root cause: A control component deployed with no authentication and exposed to a wide network—precisely the K09 failure mode.

Case Class 2: Exposed etcd Disclosing Every Secret

Misconfiguration: etcd listening for client traffic on a routable interface without client-certificate authentication, or an etcd snapshot/backup left readable.

Impact: Anyone reaching the port could dump every key, including all Kubernetes Secrets (database passwords, tokens, TLS keys) stored without encryption-at-rest. One reachable database equals the entire cluster's credentials.

Root cause: Missing mTLS on etcd plus missing encryption-at-rest—the datastore treated as if it were on a trusted, private wire when it was not.

Case Class 3: Open Kubelet Enabling Node-Level Code Execution

Misconfiguration: Kubelets running with anonymous authentication and AlwaysAllow authorization, exposing the full API on 10250 (and often the read-only 10255).

Impact: Attackers enumerated pods through the kubelet, then used /exec to run commands inside containers—harvesting service-account tokens and mounted Secrets, then using those tokens against the API server to spread. Research tooling has repeatedly demonstrated this exact chain against internet-exposed kubelets.

Root cause: The node agent's own authentication and authorization left at insecure values, a setting entirely separate from—and often forgotten alongside—the API server's.

Prevalence and Detectability

Component misconfiguration is common on self-managed clusters and highly detectable. The security community codified exactly what "hardened" means in the CIS Kubernetes Benchmark, and the open-source tool kube-bench checks a running cluster against it automatically. That means both attackers and defenders can assess a cluster's component posture quickly.

Note: exact figures vary by report and year. The durable takeaway is that component misconfiguration is common on hand-built clusters, mechanically detectable with CIS tooling, and catastrophic when present—which is why continuous benchmarking is the backbone of the defense.

Common Misunderstandings

Myth 1: "We use a managed cluster, so the control plane is not our problem"

Reality: Managed providers harden and run the API server and etcd for you—a real reduction in risk. But you still own the kubelets, the node configuration, the add-ons, the admission-plugin choices you can influence, audit-log routing, and every self-managed component. The shared-responsibility line runs through the middle of K09, not around it.

Myth 2: "It is on a private network, so plaintext etcd is fine"

Reality: "Private" networks are routinely reached through SSRF, a compromised pod, a misrouted route, or a flat VPC. etcd holds every Secret in the cluster; it must require mutual TLS and encrypt Secrets at rest regardless of where it sits.

Myth 3: "K09 is the same as K01 insecure workloads"

Reality: K01 is a bad pod (running as root, privileged, hostPath). K09 is a bad component (an API server that answers anonymously, a kubelet with no auth). K01 lives in your manifests; K09 lives in the platform's own flags and certificates. Fixing every workload does nothing if the kubelet still executes anonymous commands.

Myth 4: "K09 is the same as K04 missing policy enforcement"

Reality: K04 is the absence of an admission policy engine (Kyverno, Gatekeeper, PSA) validating workloads. K09 is the insecure configuration of the components themselves. They are related—PodSecurity is an admission plugin configured on the API server—but K04 asks "is anything checking my pods?" while K09 asks "is the API server itself locked down?"

Myth 5: "The default flags are secure enough"

Reality: Modern Kubernetes ships far safer defaults than it used to—but hand-rolled clusters override those defaults explicitly, and in-place upgrades preserve old insecure flags. "Default" only helps if nothing overrode it, which is exactly what a benchmark scan verifies.

Myth 6: "Audit logging is a nice-to-have"

Reality: Without an audit policy the API server keeps no record of who did what. When a component misconfiguration is exploited, the audit log is the only source of truth for scope and blast radius—and its absence is itself a compliance finding.

How Misconfigured Components Differ from Related Risks

AspectK09 Misconfigured ComponentsK01 Insecure WorkloadsK04 No Policy Enforcement
What is wrongControl-plane / node component flags & certsA pod's own security contextNo engine validating workloads
Where it livesapiserver/kubelet/etcd configPod & container manifestsAdmission webhooks / PSA
Typical fixHarden flags per CIS, mTLS, disable anonDrop privileges, no hostPathInstall Kyverno/Gatekeeper/PSA
Detectionkube-bench (CIS), kubescapeManifest scan, PSA auditCheck for admission webhooks

Key Takeaways

  1. The control plane is the trust root—a single anonymous or over-permissive component collapses every control above it.
  2. Authentication and authorization apply to infrastructure too—the API server, kubelet, and etcd each need real authN/authZ and mTLS.
  3. etcd is your entire secret store—require mutual TLS, keep it private, and encrypt Secrets at rest.
  4. Kubelets are a separate attack surface—lock down 10250, disable anonymous auth, and turn off the 10255 read-only port.
  5. Benchmark continuously—the CIS Kubernetes Benchmark via kube-bench turns "is this hardened?" into an automated, repeatable check.

How to Identify if You're Vulnerable

Ask these questions about your cluster's components:

If you answered "no" or "not sure" to several of these, your cluster's foundations may be exploitable today.

Next Steps