1. Container Threat Landscape
Container Attack Surface:
Build Time:
├── Malicious base images
├── Vulnerable dependencies
├── Hardcoded secrets in Dockerfile
└── Unsigned images
Runtime:
├── Container escape (privileged mode)
├── Host filesystem access
├── Network namespace attacks
├── Resource exhaustion
└── Cryptomining
Orchestration (Kubernetes):
├── RBAC misconfiguration
├── Exposed API server
├── etcd without auth
├── Kubelet unauthenticated
├── Pod-to-pod attacks
└── Service account token abuse
Supply Chain:
├── Compromised base images
├── Typosquatting in registries
├── CI/CD pipeline poisoning
└── Unsigned artifacts
2. Docker Security Testing
# --- Image scanning with Trivy ---
# Scan image for vulnerabilities
trivy image --severity HIGH,CRITICAL myapp:latest
# Scan with SBOM output
trivy image --format cyclonedx --output sbom.json myapp:latest
# Scan Dockerfile for misconfigurations
trivy config Dockerfile
# Scan filesystem
trivy fs --scanners vuln,secret,misconfig ./
# --- Docker Bench Security ---
# CIS Docker Benchmark automated checker
docker run --rm --net host --pid host \
--userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
docker/docker-bench-security
# --- Container Escape Techniques ---
# Check if running in privileged mode
cat /proc/1/status | grep CapEff
# CapEff: 0000003fffffffff = PRIVILEGED!
# Check if Docker socket is mounted
ls -la /var/run/docker.sock
# If accessible → can create privileged containers
# Escape via Docker socket
docker -H unix:///var/run/docker.sock run -it \
--privileged --pid=host \
-v /:/host \
alpine chroot /host
# Check for sensitive mounts
mount | grep -E "(proc|sys|dev)"
cat /proc/1/cgroup | grep docker
# Check capabilities
capsh --print
# Look for: cap_sys_admin, cap_sys_ptrace, cap_net_admin
# --- Secure Dockerfile ---
# ❌ Insecure
FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3
COPY . /app
USER root
CMD ["python3", "/app/main.py"]
# ✅ Secure
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM gcr.io/distroless/python3-debian12
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --chown=65534:65534 . .
USER 65534
HEALTHCHECK --interval=30s --timeout=3s CMD ["python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')"]
CMD ["main.py"]
3. Kubernetes Security Testing
# --- K8s Enumeration ---
# Check current permissions
kubectl auth can-i --list
kubectl auth can-i create pods
kubectl auth can-i get secrets
# List all namespaces
kubectl get namespaces
# Get service account tokens
kubectl get secrets -A -o json | jq '.items[] | select(.type=="kubernetes.io/service-account-token") | .metadata.name'
# Check RBAC
kubectl get clusterrolebindings -o json | jq '.items[] | select(.subjects[]?.name=="system:anonymous")'
# Check pod security
kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[].securityContext.privileged==true) | .metadata.name'
# --- kube-hunter — K8s pentest tool ---
# Run from inside the cluster
kubectl run kube-hunter --image=aquasec/kube-hunter \
--restart=Never --command -- kube-hunter --pod
# Run from outside
docker run --rm aquasec/kube-hunter --remote
# --- kubeaudit ---
kubeaudit all -f deployment.yaml
kubeaudit all # Audit entire cluster
# --- Common K8s Misconfigurations ---
# 1. Check if API server is exposed
curl -k https://:6443/api/v1/namespaces
# If returns data without auth → critical!
# 2. Check kubelet
curl -sk https://:10250/pods
# Unauthenticated kubelet → can execute in pods
# 3. Check etcd
etcdctl --endpoints=http://:2379 get / --prefix --keys-only
# Unprotected etcd → can read ALL cluster secrets
# 4. Service account token in pod
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# Use this token to access K8s API from within pod
# 5. Check for hostPath mounts
kubectl get pods -A -o json | jq '.items[] |
select(.spec.volumes[]?.hostPath != null) |
{name: .metadata.name, paths: [.spec.volumes[] | select(.hostPath) | .hostPath.path]}'
4. Falco — Runtime Security
# Falco rules for runtime threat detection
# /etc/falco/custom_rules.yaml
- rule: Container Escape Attempt
desc: Detect attempts to escape container
condition: >
spawned_process and container and
(proc.name in (nsenter, unshare) or
proc.cmdline contains "chroot /host" or
proc.cmdline contains "/proc/1/root")
output: >
Container escape attempt detected
(user=%user.name command=%proc.cmdline
container=%container.name image=%container.image.repository)
priority: CRITICAL
tags: [container, escape]
- rule: Crypto Mining Detection
desc: Detect crypto mining processes
condition: >
spawned_process and container and
(proc.name in (xmrig, minerd, minergate, cpuminer) or
proc.cmdline contains "stratum+tcp" or
proc.cmdline contains "mining.pool")
output: >
Crypto mining detected
(user=%user.name command=%proc.cmdline
container=%container.name)
priority: CRITICAL
tags: [container, cryptomining]
- rule: Sensitive File Access
desc: Detect access to sensitive files
condition: >
open_read and container and
(fd.name startswith /etc/shadow or
fd.name startswith /etc/passwd or
fd.name startswith /proc/1/ or
fd.name contains serviceaccount/token)
output: >
Sensitive file accessed
(user=%user.name file=%fd.name
container=%container.name)
priority: HIGH
tags: [container, filesystem]
# Deploy Falco on Kubernetes
# helm install
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set falcosidekick.enabled=true \
--set falcosidekick.config.slack.webhookurl="https://hooks.slack.com/..." \
--set falcosidekick.config.slack.minimumpriority="warning"
5. Supply Chain Security
# --- Image signing with Cosign ---
# Sign image
cosign sign --key cosign.key myregistry.com/myapp:v1.0
# Verify signature
cosign verify --key cosign.pub myregistry.com/myapp:v1.0
# --- SBOM generation ---
# Syft — SBOM generator
syft myapp:latest -o cyclonedx-json > sbom.json
# Grype — vulnerability scanner using SBOM
grype sbom:sbom.json --by-cve --fail-on high
# --- Admission control ---
# Kyverno policy — require signed images
# kyverno-policy.yaml — Require image signatures
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
background: false
rules:
- name: verify-cosign-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "myregistry.com/*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----
6. K8s Security Checklist
Kubernetes Pentest Checklist:
API Server:
□ Authentication required (no anonymous access)
□ RBAC enforced (no permissive ClusterRoleBindings)
□ Audit logging enabled
□ API server not publicly exposed
Workloads:
□ No privileged containers
□ No host namespace sharing (PID, Network, IPC)
□ No hostPath volume mounts
□ Resource limits set (CPU, memory)
□ Read-only root filesystem
□ Non-root user (runAsNonRoot: true)
□ Drop all capabilities, add only needed
Network:
□ Network Policies applied (deny by default)
□ Pod-to-pod communication restricted
□ Ingress TLS configured
□ Service mesh with mTLS
Secrets:
□ Secrets encrypted at rest (EncryptionConfiguration)
□ External secret management (Vault, AWS SM)
□ No secrets in environment variables
□ Service account tokens auto-mounted only when needed
Supply Chain:
□ Images from trusted registries only
□ Image signatures verified (Cosign + admission)
□ Base images regularly updated
□ SBOM generated and scanned
7. Summary
- Docker: Trivy scanning, Docker Bench, container escape detection
- Kubernetes: RBAC audit, API server, kubelet, etcd security
- Falco: Runtime threat detection — escape, cryptomining, sensitive access
- Supply Chain: Cosign signing, SBOM, Kyverno admission control
- Defense: Non-root, drop capabilities, network policies, encrypted secrets
The next article will focus on API Security Testing — OWASP API Top 10.