Back

K01: Insecure Workload Configurations - Overview

What are Insecure Workload Configurations?

K01: Insecure Workload Configurations is the first entry in the OWASP Kubernetes Top 10. It covers Pods, Deployments, DaemonSets, and every other workload that is admitted to a cluster with a securityContext (or pod spec) that hands an attacker an easy path to escalate. The vulnerability is not in the application code running inside the container—it is in the manifest: the YAML that tells the kubelet and container runtime how much of the host to expose to that container.

Kubernetes gives a workload access to the host in proportion to what the manifest asks for. Ask for nothing, and the container is a reasonably well-isolated process. Ask for privileged: true, host namespaces, host paths, or dangerous Linux capabilities, and the "container boundary" becomes a formality an attacker steps over in seconds. Because these fields default to the permissive side for backward compatibility, a workload that never mentions security is already less safe than it could be.

Core Concept

Hardened workload (least privilege):
  runAsNonRoot            -> true, with an explicit non-zero runAsUser
  allowPrivilegeEscalation -> false (no setuid gain of new privileges)
  privileged              -> false (no full device / host access)
  capabilities            -> drop ["ALL"], add back nothing (or one, narrowly)
  readOnlyRootFilesystem  -> true (writable dirs mounted explicitly)
  seccompProfile          -> RuntimeDefault (syscall filtering on)
  host namespaces         -> hostPID / hostIPC / hostNetwork all false
  hostPath volumes        -> none (no /, no /var/run/docker.sock)
  automountServiceAccountToken -> false unless the app calls the API
  resources.limits        -> cpu / memory / ephemeral-storage set

Insecure workload (easy escalation):
  privileged: true                 -> container ~= root on the node
  hostPID: true / hostIPC: true    -> see and signal host processes
  hostNetwork: true                -> host NICs, localhost services, metadata
  hostPath: / or docker.sock       -> read/write the node filesystem or runtime
  runAsNonRoot: false / uid 0       -> root inside the container
  allowPrivilegeEscalation: true   -> setuid binaries can gain privileges
  capabilities.add: [SYS_ADMIN]    -> mount, ptrace, escape primitives
  seccomp: Unconfined              -> full syscall surface to the kernel
  default ServiceAccount token mounted -> cluster credential handed to attacker

Why It's Critical for Kubernetes

Kubernetes changes the blast radius of a single bad setting. On a traditional server, a compromised process is on one machine. In a cluster, several conditions amplify the damage:

Why Does This Matter?

Business Impact

Technical Impact

Technical Context

The Dangerous Fields, One by One

1. Privileged Containers

securityContext:
  privileged: true

A privileged container runs with nearly all capabilities, an unconfined seccomp/AppArmor profile, and access to all host devices under /dev. It is effectively root on the node. This single flag defeats almost every other isolation control at once and is the most direct escape primitive in Kubernetes.

2. Host Namespaces (hostPID / hostIPC / hostNetwork)

spec:
  hostPID: true       # see and signal every process on the node
  hostIPC: true       # access host shared memory / IPC
  hostNetwork: true   # use the node's network stack directly

Risk: hostPID exposes other processes (and their /proc, environment variables, and open file descriptors) for inspection and injection. hostNetwork reaches services bound to the node's localhost (often unauthenticated) and the cloud metadata endpoint, and bypasses NetworkPolicy.

3. Host Path Mounts

volumes:
  - name: host-root
    hostPath:
      path: /                       # entire node filesystem
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock    # the container runtime socket

Risk: Mounting the node root or the runtime socket is a direct escape. With the socket, an attacker starts a new container that mounts the host and runs as root. With /, they read kubelet credentials and write to sensitive paths.

4. Running as Root and Privilege Escalation

securityContext:
  runAsNonRoot: false     # (or simply unset) -> UID 0 allowed
  # runAsUser omitted     -> image default, often root
  allowPrivilegeEscalation: true

Risk: A container running as UID 0 that also permits privilege escalation lets any foothold reach full in-container root, then leverage capabilities or a kernel bug against the host.

5. Dangerous Added Capabilities

securityContext:
  capabilities:
    add: ["SYS_ADMIN", "NET_ADMIN", "SYS_PTRACE"]

Risk: SYS_ADMIN alone enables mount operations and many escape techniques; SYS_PTRACE allows inspecting and manipulating other processes; NET_ADMIN allows network manipulation and traffic interception. Most workloads need none of these.

6. Unconfined seccomp / AppArmor

securityContext:
  seccompProfile:
    type: Unconfined      # no syscall filtering
# or annotation: container.apparmor.security.beta.kubernetes.io/... : unconfined

Risk: Disabling syscall filtering exposes the full kernel API to the container, widening the surface for kernel exploits used in escapes.

7. Writable Root Filesystem and Missing Resource Limits

securityContext:
  readOnlyRootFilesystem: false   # attacker can drop tools / persist
resources: {}                     # no cpu/memory limits -> noisy-neighbour DoS

Risk: A writable root filesystem lets an attacker install tooling and persist; missing limits let a single Pod exhaust a node.

8. Automounted Default ServiceAccount Token

# Default behaviour: a token for the namespace's default ServiceAccount
# is mounted at /var/run/secrets/kubernetes.io/serviceaccount/token

Risk: If the app never calls the Kubernetes API, this token is pure downside—code execution in the Pod hands the attacker a cluster credential to enumerate and, depending on RBAC, escalate.

Where the Configuration Lives

FieldInsecure SettingEscalation It Enables
privilegedtrueFull node access; near-instant escape
hostPID / hostIPC / hostNetworktrueHost process/IPC/network access, metadata reach
hostPath/, docker.sockNode filesystem or runtime takeover
runAsNonRootfalse / unsetRoot inside container
allowPrivilegeEscalationtruesetuid gain of new privileges
capabilities.addSYS_ADMIN, NET_ADMINMount, ptrace, network escape primitives
seccompProfileUnconfinedFull kernel syscall surface
automountServiceAccountTokentrue (default)Cluster credential theft

Real-World Impact

The incidents below are described as verifiable classes of attack that are repeatedly documented in public research and post-mortems. They avoid precise fabricated figures; the durable lesson is the pattern, not a single number.

Case Class 1: Privileged-Container Escape to the Node

Misconfiguration:

Impact: Because the container is privileged, the attacker uses a standard breakout technique (writing to host devices, abusing cgroups release-agent, or mounting the host filesystem) to run code on the node, then reads every co-located Pod's secrets. Root cause: a workload granted host-equivalent power for convenience, with no admission control to stop it.

Case Class 2: Exposed Container Runtime Socket (docker.sock)

Misconfiguration:

Impact: Any code in that Pod can talk to the runtime directly and launch a new container that is privileged and mounts the host root, achieving node takeover without any kernel exploit at all. Root cause: handing a workload control of the very runtime that is supposed to contain it.

Case Class 3: Cryptojacking of Misconfigured Workloads (Tesla-style)

Misconfiguration:

Impact: Attackers deployed cryptomining workloads inside the cluster (cryptojacking) and could reach non-public cloud resources. Root cause: a management surface plus permissive workload settings that let untrusted actors run arbitrary, unrestricted containers.

Note: specifics vary by incident and year. Treat each case as a class of failure—privileged escape, runtime-socket exposure, and cryptojacking of open/permissive workloads are all repeatedly observed. The takeaway is the mechanism, not an exact statistic.

Prevalence and Statistics

Insecure Workload Configurations is placed first in the OWASP Kubernetes Top 10 for good reason: it is both common and high-impact. Because permissive fields exist for backward compatibility and many popular Helm charts historically shipped without a hardened securityContext, insecure workloads appear in a large share of real clusters.

Rather than cite precise percentages (which vary by scanner and dataset), the defensible picture is:

The durable takeaway: insecure workload configuration is prevalent, trivially detectable with off-the-shelf scanners, and—when it involves privilege—among the highest-severity issues a cluster can carry.

Common Misunderstandings

Myth 1: "Containers are isolated, so the securityContext is optional"

Reality: Containers share the host kernel. Isolation is a set of Linux features (namespaces, cgroups, capabilities, seccomp) that the manifest can weaken or switch off. A permissive workload is not "isolated with a small caveat"—it is a normal host process wearing a thin costume.

Myth 2: "We run as root inside the container, but that's not host root"

Reality: Without user namespaces (off by default in most clusters), UID 0 in the container maps to UID 0 on the host. Combined with a writable hostPath, an added capability, or a kernel bug, in-container root becomes host root quickly.

Myth 3: "Our app doesn't use the Kubernetes API, so the token doesn't matter"

Reality: If the app never calls the API, the automounted token is pure risk with no benefit. An attacker who lands in the Pod inherits a valid cluster credential. Set automountServiceAccountToken: false.

Myth 4: "Only the CI/build workload is privileged, and that's fine"

Reality: Build and CI workloads process untrusted input (pull requests, dependencies, images) and are prime targets. A privileged build Pod is one of the most dangerous things in a cluster, not an acceptable exception.

Myth 5: "Pod Security Policies are deprecated, so there's nothing to enforce with"

Reality: PSP was replaced by Pod Security Admission (built-in, with baseline and restricted levels) and by policy engines like Kyverno and OPA Gatekeeper. Enforcement is more capable now, not absent.

Myth 6: "NetworkPolicy or a firewall will contain a privileged container"

Reality: A container that escapes to the node operates with the node's identity and network position, and hostNetwork bypasses NetworkPolicy entirely. Network controls do not contain a host-level compromise.

How K01 Differs from Related Kubernetes Risks

AspectK01 Insecure Workload ConfigK03 Overly Permissive RBACK08 Secrets Management
Root causePermissive pod/securityContext fieldsBroad roles and bindingsSecrets exposed or unencrypted
Where it livesWorkload manifestsRole / RoleBinding objectsSecret objects, mounts, etcd
Typical fixHarden securityContext, admission policyLeast-privilege RBACEncrypt, scope, rotate
DetectionManifest scan, PSA, Kyverno/GatekeeperRBAC auditSecret scan, etcd config

Key Takeaways

  1. The manifest is the security boundary—what the workload asks for is what the attacker gets.
  2. Defaults lean permissive; a workload that never sets a securityContext is already weaker than it should be.
  3. Privilege, host namespaces, and hostPath are escape primitives—treat any of them as a node-compromise risk.
  4. Every Pod is a cluster identity—disable token automount when the app doesn't need the API.
  5. Enforce, don't hope—Pod Security Admission and policy engines make hardened configuration the only configuration that admits.

How to Identify if You're Vulnerable

Ask these questions about your workloads:

If you answered "no" or "not sure" to several of these, you likely have exploitable insecure workloads today.

Next Steps