A bank campus with every door open
Watch it happen
Mallory breaks into the small website branch. That branch is privileged, the doors between branches are open and a password sits on a plain note, so she reaches the customer data.
Mallory walks into a campus of small bank branches, looking for the weakest one.
Mallory says: Which branch is easiest?In bank terms and app terms
| In the bank | In your app |
|---|---|
Are you exposed?
Your manifests contain privileged: true, runAsUser: 0, hostNetwork or capabilities add ALL. Passwords, API keys or database URLs are written directly in env values or values.yaml. You use image: something:latest and have no resource limits or network policies.
Set runAsNonRoot: true, privileged: false, allowPrivilegeEscalation: false, drop ALL capabilities, and avoid hostPath mounts. Store credentials in Kubernetes Secrets (or an external secret manager) and reference them with secretKeyRef. Secrets are only base64-encoded, so restrict who can read them (RBAC) and enable encryption at rest. Add CPU and memory limits, a default-deny NetworkPolicy (your network plugin must enforce it), and pinned image versions.
It has happened to real companies
Tesla (2018) — Researchers at RedLock found a Kubernetes dashboard on Tesla's AWS account with no password. It exposed AWS credentials, and attackers had used it to run cryptocurrency mining.
Docker runc CVE-2019-5736 (2019) — A flaw in the runc container runtime let an attacker who could run a command as root inside a container overwrite the host's runc binary and gain root on the host. It was fixed in Docker 18.09.2, and user namespaces that do not map the host's root into the container also blocked it.
What it looks like in code
# GOOD: Secure pod security context
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: app
securityContext:
privileged: false
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "100m"
memory: "128Mi"
Ask your AI tool to fix it
Paste this into Cursor, Claude, Lovable, Bolt or whatever you build with.
Review all Kubernetes manifests and Helm values. Remove privileged mode, host namespaces, hostPath mounts and added capabilities; set runAsNonRoot, allowPrivilegeEscalation: false and drop ALL capabilities; move any plaintext secrets to Kubernetes Secrets referenced via secretKeyRef; pin image tags; add CPU and memory limits; and add a default-deny NetworkPolicy with explicit allow rules. Summarize each change.Where this comes from
The facts, figures and fixes on this page were checked against these sources on 25 Oct 2026. They are linked so you can check for yourself.
- Pod Security StandardsKuberneteshost namespaces, hostPath, privileged and runAsNonRoot rules in the profiles
- Network PoliciesKubernetespods accept all traffic until a policy selects them; plugin must enforce
- SecretsKubernetesSecrets are stored unencrypted by default; enable encryption at rest and RBAC
- Configure a Security ContextKubernetesallowPrivilegeEscalation and dropping capabilities in the pod spec
- CVE-2019-5736 runc container breakout advisorySeclists (oss-sec)runc flaw lets a container overwrite host runc; user namespaces block it
- CVE-2019-5736 (runc)GitHub Advisory Databaserunc flaw affected Docker before 18.09.2; host root access
Spot a mistake or something out of date? Report a correction · How these guides are made and checked
The free, open-source scanner checks for most of the problems in these guides.