📋 What Is It?
Insecure Workload Configurations is about the manifest, not the app code. Pods and Deployments admitted with permissive securityContext fields - privileged: true, host namespaces, hostPath mounts, or dangerous Linux capabilities - turn the container boundary into a formality an attacker steps over in seconds. Because these fields default to the permissive side for backward compatibility, a workload that never sets a securityContext is already weaker than it should be.
K01
OWASP Rank
Manifest
Focus Area
Easy
To Prevent
⚠️ Common Exploits
- Privileged Escape:
privileged: truemounts a host disk device and writes to the node - Runtime Socket Abuse: A mounted
docker.socklaunches a new privileged container that owns the node - hostPath Node Access: A
hostPath: /mount reads kubelet creds and drops static-pod manifests - Host PID Inspection:
hostPID: truereads other processes'/proc/<pid>/environfor secrets - Host Network + Metadata:
hostNetwork: truereaches the kubelet and cloud IAM metadata, bypassing NetworkPolicy - Token Theft: The automounted default ServiceAccount token is a ready-made cluster credential
- Capability Abuse: Added
SYS_ADMINenables the cgroup release_agent escape without full privilege
🔴 Attack Flow
1. Foothold: code execution in a container
↓
2. Enumerate the sandbox (id, capsh, mounts, token)
↓
3. Escape via privileged / hostPath / docker.sock
↓
4. Loot node: kubelet creds, other Pods' secrets, metadata
↓
5. IMPACT: Stolen token drives cluster-wide takeover!
↓
2. Enumerate the sandbox (id, capsh, mounts, token)
↓
3. Escape via privileged / hostPath / docker.sock
↓
4. Loot node: kubelet creds, other Pods' secrets, metadata
↓
5. IMPACT: Stolen token drives cluster-wide takeover!
❌ Vulnerable Code
# Bad: every escape primitive in one manifest
apiVersion: v1
kind: Pod
metadata:
name: legacy-agent
spec:
hostPID: true # sees all host processes
hostIPC: true # host shared memory
hostNetwork: true # host NICs + metadata reach
containers:
- name: agent
image: agent:latest # mutable tag, unknown provenance
securityContext:
privileged: true # ~= root on the node
runAsUser: 0 # root in container
allowPrivilegeEscalation: true
readOnlyRootFilesystem: false
capabilities:
add: ["SYS_ADMIN", "NET_ADMIN"] # escape primitives
seccompProfile:
type: Unconfined # full kernel syscall surface
volumeMounts:
- name: host-root
mountPath: /host # entire node filesystem
- name: docker-sock
mountPath: /var/run/docker.sock # runtime takeover
# no resources.limits -> noisy-neighbour DoS
volumes:
- name: host-root
hostPath: { path: / }
- name: docker-sock
hostPath: { path: /var/run/docker.sock }
# default ServiceAccount token automounted -> cluster credential
✅ Secure Code
# Good: least-privilege, hardened securityContext
apiVersion: v1
kind: Pod
metadata:
name: agent
spec:
hostPID: false
hostIPC: false
hostNetwork: false
automountServiceAccountToken: false # app doesn't call the API
securityContext: # Pod-level
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
seccompProfile:
type: RuntimeDefault # syscall filtering on
containers:
- name: agent
image: registry.example.com/agent@sha256:<digest> # pinned by digest
securityContext: # container-level wins
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 10001
capabilities:
drop: ["ALL"] # add back nothing
resources:
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "500m", memory: "256Mi", ephemeral-storage: "1Gi" }
volumeMounts:
- name: tmp
mountPath: /tmp # writable scratch, not the host
volumes:
- name: tmp
emptyDir: {}
# no hostPath, no docker.sock, no host namespaces
✓ Prevention Checklist
- Set
runAsNonRoot: truewith an explicit non-zerorunAsUser - Set
allowPrivilegeEscalation: falseandprivileged: false - Drop
ALLcapabilities, add back only the one strictly needed - Set
readOnlyRootFilesystem: true; mount writable dirs explicitly - Use
seccompProfile: RuntimeDefault, neverUnconfined - Forbid
hostPID,hostIPC,hostNetworkand allhostPathmounts - Never mount the container runtime socket; use a rootless builder (Kaniko)
- Set
automountServiceAccountToken: falsewhere the API isn't used - Set CPU, memory, and ephemeral-storage limits on every container
- Enforce Pod Security Admission (
restricted) plus Kyverno/Gatekeeper - Scan manifests in CI (Trivy, kubescape, kube-linter) before they reach the cluster
🔍 Detection & Tools
Scanning & Policy:
kube-bench
kubeaudit
Trivy
kubescape
Polaris
kube-linter
Checkov
Admission & Runtime:
Pod Security Admission
Kyverno
OPA/Gatekeeper
Falco
How to Test:
- Find privileged Pods:
kubectl get pods -A -o json | jq ...privileged==true - List Pods using
hostPID/hostIPC/hostNetwork - Flag
hostPathvolumes, especially/anddocker.sock - Dry-run
restrictedPSA:kubectl label --dry-run=server ns ... - Run
trivy config ./k8sandkubescape scan framework nsa ./k8s
🌍 Real-World
- Privileged-container escape to the node: A build/CI/monitoring agent granted
privilegedorSYS_ADMIN"for convenience" becomes a node compromise once an app flaw gives code execution inside it. - Exposed runtime socket (docker.sock): The docker-in-docker build pattern mounts the runtime socket; any code in the Pod launches a privileged host-mounting container - node takeover with no kernel exploit.
- Tesla cryptojacking (2018, widely reported): An administrative Kubernetes dashboard was reachable without authentication; attackers scheduled their own cryptomining Pods and reached cloud resources - a management surface plus permissive workloads.
- Note: Treat each as a class of failure. Privileged escape, runtime-socket exposure, and cryptojacking of open/permissive workloads are repeatedly observed; the takeaway is the mechanism, not an exact statistic.
📌 Quick Tips
- DO NOT set
privileged: true - DO NOT mount
hostPath: /or the runtime socket - DO NOT enable host namespaces
- DO run as non-root and drop ALL capabilities
- DO disable token automount when unused
- DO enforce restricted Pod Security Admission
- DO scan manifests in CI
📜 Compliance
Related Standards:
- CIS Kubernetes Benchmark - Pod Security
- NSA/CISA Kubernetes Hardening Guidance
- NIST 800-190 Application Container Security
- PCI-DSS Requirement 2.2 - Secure Configuration
- Pod Security Standards restricted profile