Container & Image Vulnerabilities
Container & Image Vulnerabilities at a glance
Overview
Containers package applications with their dependencies, but this convenience can also package security vulnerabilities. Container security requires vigilance across the entire lifecycle: base image selection, build process, secret management, and runtime configuration.
Common container vulnerabilities include using outdated base images with known CVEs, embedding secrets (API keys, passwords) in image layers, running containers as root, mounting sensitive host directories, using overly broad capabilities, pulling images from untrusted registries, and missing vulnerability scanning in CI/CD pipelines.
Where it occurs
Container vulnerabilities occur in images or deployments with outdated packages, embedded secrets, root privileges, excessive permissions, untrusted sources, or missing security scanning in pipelines.
Impact
Container vulnerabilities lead to application compromise through vulnerable dependencies, container escape and host system access, secret exposure affecting multiple environments, privilege escalation from root containers, lateral movement through shared networks, supply chain attacks through compromised images, and compliance violations.
Prevention
Prevent container compromise by using minimal, up-to-date images, scanning for vulnerabilities, avoiding embedded secrets, running as non-root with limited capabilities, enforcing resource and network limits, signing images, and using security profiles.
Examples
Switch tabs to view language/framework variants.
Docker image contains hardcoded credentials
Secrets embedded in Docker image layers.
FROM node:18
WORKDIR /app
COPY . .
# BUG: Hardcoded secret in image
ENV API_KEY=sk-1234567890abcdef
RUN npm install
CMD ["npm", "start"]- Line 5: Hardcoded secret in ENV
Secrets in images are visible to anyone who can pull the image.
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# Don't hardcode secrets - use secrets management
CMD ["npm", "start"]
# Use secrets at runtime:
# docker run -e API_KEY="$(cat /run/secrets/api_key)" company/app- Line 7: No embedded secrets
- Line 10: Runtime secret injection
Use Docker secrets, Kubernetes secrets, or environment variables at runtime.
Engineer Checklist
-
Use minimal base images (alpine, distroless)
-
Scan images for vulnerabilities in CI/CD pipeline
-
Update base images and dependencies regularly
-
Never embed secrets in Dockerfile or image layers
-
Use secret management (Vault, Kubernetes Secrets, AWS Secrets Manager)
-
Run containers as non-root user (USER directive)
-
Use read-only root filesystem where possible
-
Drop unnecessary Linux capabilities
-
Implement resource limits (CPU, memory)
-
Sign and verify container images
-
Pull images only from trusted registries
-
Don't mount sensitive host directories
-
Use network policies to restrict communication
-
Implement AppArmor/SELinux profiles
-
Scan for secrets in images before pushing
End-to-End Example
A container image embeds database credentials in an environment variable, exposing them to anyone who can pull the image.
# Vulnerable Dockerfile
FROM node:14
ENV DATABASE_PASSWORD=supersecret123
COPY . /app
CMD ["node", "server.js"]# Secure Dockerfile
FROM node:14-alpine
# Run as non-root
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
USER nodejs
COPY --chown=nodejs:nodejs . /app
WORKDIR /app
# Secrets injected at runtime from secret manager
CMD ["node", "server.js"]Discovery
Pull container images and examine layer history with 'docker history' or extract filesystem to find embedded secrets.
-
1. Inspect image layer history for secrets
cliAction
docker history company/app:latest --no-trunc | grep -iE '(password|secret|key|token)'
Expected Result
ENV DATABASE_PASSWORD=prod_db_pass_2024 visible in layer at step 4/12, along with AWS_SECRET_KEY in step 7/12
Artifacts
database_credentials aws_keys plaintext_secrets -
2. Extract and search filesystem layers
cliAction
docker save company/app:latest -o app.tar && tar -xf app.tar && find . -name '*.json' -o -name '*.env' | xargs grep -i secret
Expected Result
Multiple config files contain hardcoded API keys, database URLs with embedded credentials, and JWT signing secrets
Artifacts
config_leakage api_keys jwt_secrets -
3. Check container security context
cliAction
docker inspect company/app:latest | jq '.[]|{User:.Config.User, Privileged:.HostConfig.Privileged, Capabilities:.HostConfig.CapAdd}'
Expected Result
User field is empty (runs as root), CapAdd includes SYS_ADMIN and NET_ADMIN
Artifacts
root_execution excessive_capabilities privileged_mode
Exploit steps
Attacker obtains container image, extracts layers, and finds embedded credentials in environment variables or configuration files, then uses them to access production systems.
-
1. Harvest credentials from public registry
cliAction
docker pull company/api:v2.3.1 && docker history company/api:v2.3.1 --no-trunc --format '{{.CreatedBy}}' | grep -oE 'ENV [A-Z_]+=.+' > secrets.txt
Response
Extracted DATABASE_URL=postgresql://admin:S3cr3tP@ss@prod-db.internal:5432/maindb, STRIPE_SECRET_KEY=sk_live_51Hx..., JWT_SECRET=my-super-secret-key-2024
Artifacts
database_url stripe_api_key jwt_signing_secret production_access -
2. Break into production database
cliAction
psql postgresql://admin:S3cr3tP@ss@prod-db.internal:5432/maindb -c 'SELECT email, password_hash, credit_card_last4 FROM users LIMIT 10000;'
Response
Successfully connected to production database. Extracted 10,000 user records including PII and payment information.
Artifacts
user_pii password_hashes payment_data gdpr_breach -
3. Forge admin JWT tokens
cliAction
Use extracted JWT secret to create admin tokens: jwt encode --secret 'my-super-secret-key-2024' '{"user_id":1,"role":"admin","exp":9999999999}'
Response
Generated valid admin JWT. Used to access /admin/users endpoint and create new admin accounts.
Artifacts
forged_jwt admin_access account_creation platform_takeover
Specific Impact
Secret exposure leading to unauthorized database access, API abuse, and potential compromise of multiple environments using the same credentials.
Fix
Never embed secrets in container images. Use runtime secret injection from secure secret management systems. Run containers as non-root users. Use minimal base images to reduce vulnerabilities.
Detect This Vulnerability in Your Code
Sourcery automatically identifies container & image vulnerabilities vulnerabilities and many other security issues in your codebase.
Scan Your Code for Free