Welcome to from-docker-to-kubernetes

Docker Image Security Scanning

Understanding and implementing security scanning for Docker images to identify vulnerabilities and ensure container security

Introduction to Docker Image Security Scanning

Docker image security scanning is a critical practice in container security that involves analyzing container images to identify known vulnerabilities, misconfigurations, sensitive data exposure, and compliance issues. In today's threat landscape, where supply chain attacks and application vulnerabilities are increasingly common, implementing robust security scanning for container images has become an essential component of secure DevOps practices.

Container images serve as the foundation for all containerized applications, bundling application code with its dependencies, configuration files, and runtime environments. This self-contained nature, while beneficial for deployment consistency, creates unique security challenges:

  1. Dependency Vulnerabilities: Images typically contain hundreds or thousands of packages and dependencies, each potentially introducing security vulnerabilities.
  2. Image Layering Complexity: The layered nature of Docker images means vulnerabilities can be introduced and then obscured across multiple build stages.
  3. Supply Chain Risks: Base images and dependencies pulled from public registries may contain malicious code or backdoors.
  4. Configuration Issues: Hardcoded secrets, overly permissive settings, and insecure defaults can create security weaknesses.
  5. Outdated Components: Images that aren't regularly updated may contain known vulnerabilities that have fixes available.

Image security scanning addresses these challenges by providing visibility into the contents of container images, allowing organizations to detect security issues before images are deployed to production environments. This "shift-left" approach to security helps prevent vulnerable containers from entering the production environment in the first place, significantly reducing the attack surface.

Types of Container Image Vulnerabilities

Docker image security scanning detects various types of vulnerabilities and security issues:

Operating System Vulnerabilities

  • Weaknesses in base image OS packages and libraries
  • Common Vulnerabilities and Exposures (CVEs) in system components
  • Outdated OS packages with known security flaws
  • Kernel vulnerabilities that could enable container escapes
  • Critical security patches missing from base images
  • Default OS configurations that don't align with security best practices
  • Example: CVE-2021-44228 (Log4Shell) affecting Java-based applications

Application Dependencies

  • Vulnerabilities in language-specific packages (npm, PyPI, RubyGems, etc.)
  • Transitive dependencies with security issues
  • Outdated libraries with known exploits
  • Malicious packages introduced through typosquatting or dependency confusion
  • Using non-pinned dependency versions that could introduce vulnerabilities
  • Unmaintained or abandoned dependencies that no longer receive security updates
  • Example: A web application using a vulnerable version of a cryptographic library

Configuration Issues

  • Hardcoded credentials and API keys
  • Overly permissive file permissions
  • Running containers as root unnecessarily
  • Exposed unnecessary ports
  • Insecure default configurations
  • Missing security-related headers or settings
  • Use of deprecated or insecure protocols
  • Example: Docker image containing AWS access keys in environment variables

Malware and Backdoors

  • Malicious code embedded in public base images
  • Cryptocurrency miners hidden in container layers
  • Backdoors and reverse shells in dependencies
  • Trojans in pre-built application components
  • Command and control infrastructure for botnets
  • Data exfiltration mechanisms
  • Example: Cryptomining malware embedded in a public application image

Compliance Violations

  • Unauthorized or non-compliant base images
  • Missing required security controls
  • Non-compliant configurations for regulated industries
  • Unauthorized open-source licenses
  • Components violating export control regulations
  • Prohibited software components per organizational policies
  • Example: Using GPL-licensed code in a proprietary application without proper disclosure

Security Scanning Tools and Technologies

Several tools are available for scanning Docker images, each with different capabilities and focus areas:

# Using Trivy (popular open-source vulnerability scanner)
trivy image nginx:latest

# Scanning with detailed output and filtering for high/critical issues
trivy image --severity HIGH,CRITICAL --output trivy-results.json python:3.9

# Using Docker Scout (Docker's built-in scanning capability)
docker scout cves nginx:latest

# Using Snyk for more comprehensive analysis
snyk container test nginx:latest

# Using Anchore Engine for policy-based scanning
anchore-cli image add docker.io/library/ubuntu:20.04
anchore-cli image wait docker.io/library/ubuntu:20.04
anchore-cli image vuln docker.io/library/ubuntu:20.04 all

# Using Clair (by CoreOS) for vulnerability scanning
# (Typically deployed as a service rather than CLI)

Each of these commands will analyze the specified container image, identifying known vulnerabilities based on the tool's vulnerability database. The output typically includes the vulnerability ID (such as a CVE number), severity, affected package, vulnerable version, fixed version (if available), and sometimes additional context like exploit availability or CVSS score.

Implementing Image Scanning in CI/CD Pipelines

Integrating security scanning into CI/CD pipelines ensures that every image is automatically scanned before deployment:

Advanced Scanning Techniques

Beyond basic vulnerability scanning, advanced techniques provide deeper security insights:

Baseline Comparisons

  • Compare scan results against a known-good baseline
  • Track new vulnerabilities introduced in each build
  • Create differential reports highlighting changes
  • Maintain version history of security posture
  • Example with Trivy:
    # Scan baseline image and save results
    trivy image --format json --output baseline.json myapp:v1.0
    
    # Scan new image
    trivy image --format json --output new.json myapp:v1.1
    
    # Compare results (using jq)
    jq -s '.[1].Results[].Vulnerabilities[] | select(.VulnerabilityID as $id | .[0].Results[].Vulnerabilities[] | .VulnerabilityID != $id)' baseline.json new.json > new_vulnerabilities.json
    

Custom Policy Enforcement

  • Create organization-specific security policies
  • Define allowed/denied base images
  • Implement checks for organizational requirements
  • Enforce industry-specific compliance standards
  • Example with Open Policy Agent (OPA):
    # policy.rego
    package main
    
    deny[msg] {
      input.Config.User == "root"
      msg = "Images must not run as root user"
    }
    
    deny[msg] {
      input.Config.Env[_] = env
      contains(env, "AWS_SECRET_ACCESS_KEY=")
      msg = "AWS credentials must not be embedded in the image"
    }
    
    deny[msg] {
      input.Config.Env[_] = env
      contains(env, "PASSWORD=")
      msg = "Plain text passwords must not be embedded in the image"
    }
    

Dynamic Analysis

  • Execute images in sandboxed environments
  • Analyze runtime behavior for security issues
  • Detect anomalous behavior during container startup
  • Identify suspicious network connections
  • Example with Falco:
    # falco_rules.yaml
    - rule: Detect Crypto Miners
      desc: Detect cryptocurrency mining processes
      condition: spawned_process and proc.name in (xmrig, cryptonight, stratum, cpuminer)
      output: "Potential crypto miner detected (command=%proc.cmdline)"
      priority: CRITICAL
    
    - rule: Detect Data Exfiltration
      desc: Detect unusual outbound connections
      condition: outbound and not dest.ip in (trusted_ips) and not dest.name in (trusted_domains)
      output: "Unexpected outbound connection to %dest.ip:%dest.port"
      priority: WARNING
    

Software Composition Analysis

  • Create software bill of materials (SBOM) for images
  • Track open source components and licenses
  • Identify deprecated or unmaintained dependencies
  • Map components to known vulnerabilities
  • Example with Syft:
    # Generate SBOM
    syft packages myapp:latest -o json > sbom.json
    
    # Analyze SBOM for vulnerabilities
    grype sbom:sbom.json
    
    # Export SBOM in CycloneDX format for further analysis
    syft packages myapp:latest -o cyclonedx-json > cyclonedx-sbom.json
    

Secret Scanning

  • Detect secrets and credentials in image layers
  • Find API keys, tokens, and passwords
  • Identify SSH keys and certificates
  • Alert on potentially sensitive configuration
  • Example with TruffleHog:
    # Scan Docker image for secrets
    trufflehog docker --image myapp:latest
    
    # Scan with custom rules
    trufflehog docker --image myapp:latest --rules custom-rules.json
    

Vulnerability Management and Remediation

Discovering vulnerabilities is only half the battle; effectively managing and remediating them is equally important:

  1. Vulnerability Prioritization
    • Assess risk based on CVSS scores and exploitability
    • Consider the context of the affected component
    • Evaluate accessibility of the vulnerable component
    • Prioritize vulnerabilities with known exploits
    • Example risk scoring matrix:
      Critical: CVSS 9.0-10.0 or any exploitable vulnerability in a public-facing component
      High: CVSS 7.0-8.9 or vulnerabilities in authentication components
      Medium: CVSS 4.0-6.9 in internal components
      Low: CVSS 0.1-3.9 in non-critical components
      
  2. Automated Remediation Strategies
    • Implement automatic base image updates
    • Configure dependabot or similar tools for dependencies
    • Create automated PR workflows for vulnerability fixes
    • Example GitHub workflow for automated updates:
      name: Dependency Update
      
      on:
        schedule:
          - cron: '0 0 * * 1'  # Weekly on Monday
        workflow_dispatch:  # Allow manual trigger
      
      jobs:
        update-deps:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v3
            
            - name: Update base image
              run: |
                sed -i 's/FROM node:16/FROM node:16-slim/' Dockerfile
                docker build -t test-image .
            
            - name: Update npm dependencies
              run: npm update
            
            - name: Test application
              run: npm test
            
            - name: Create Pull Request
              uses: peter-evans/create-pull-request@v4
              with:
                title: 'chore: update dependencies to reduce vulnerabilities'
                body: 'Automated dependency updates to address security vulnerabilities.'
                branch: 'dependency-updates'
      
  3. Using Multi-Stage Builds for Security
    • Separate build and runtime environments
    • Include only necessary components in final image
    • Minimize attack surface by reducing included packages
    • Example secure multi-stage Dockerfile:
      # Build stage
      FROM node:16 AS builder
      WORKDIR /app
      COPY package*.json ./
      RUN npm ci
      COPY . .
      RUN npm run build
      
      # Security scan stage
      FROM aquasec/trivy:latest AS security-scan
      COPY --from=builder /app /app
      RUN trivy fs --security-checks vuln,config /app
      
      # Production stage
      FROM node:16-slim
      WORKDIR /app
      RUN apt-get update && apt-get upgrade -y && \
          apt-get clean && \
          rm -rf /var/lib/apt/lists/*
      USER node
      COPY --from=builder --chown=node:node /app/dist /app/dist
      COPY --from=builder --chown=node:node /app/node_modules /app/node_modules
      COPY --chown=node:node package*.json ./
      EXPOSE 3000
      CMD ["node", "dist/index.js"]
      

Best Practices for Docker Image Security

Regulatory Compliance and Auditing

Security scanning plays a crucial role in meeting regulatory requirements and industry standards:

  1. Compliance Standards Relevant to Container Security
    • PCI DSS for payment card processing
    • HIPAA for healthcare data
    • SOC 2 for service organizations
    • GDPR for EU personal data
    • FedRAMP for government systems
    • NIST 800-53 for federal information systems
    • ISO 27001 for information security management
  2. Audit-Ready Scanning Practices
    • Maintain comprehensive scan records
    • Document vulnerability remediation actions
    • Implement risk acceptance processes for exceptions
    • Create evidence trails for compliance audits
    • Example audit documentation approach:
      #!/bin/bash
      # Generate audit-ready scan report
      
      IMAGE=$1
      VERSION=$2
      DATE=$(date +%Y-%m-%d)
      
      # Create report directory
      mkdir -p "compliance/images/$IMAGE/$VERSION"
      
      # Generate vulnerability report
      trivy image --format json "$IMAGE:$VERSION" > "compliance/images/$IMAGE/$VERSION/vulnerabilities-$DATE.json"
      
      # Generate SBOM
      syft "$IMAGE:$VERSION" -o json > "compliance/images/$IMAGE/$VERSION/sbom-$DATE.json"
      
      # Document scan in audit log
      echo "[$DATE] Scanned $IMAGE:$VERSION - Report saved to compliance/images/$IMAGE/$VERSION/" >> compliance/audit-log.txt
      
      # Generate summary for review
      echo "Scan Summary for $IMAGE:$VERSION on $DATE" > "compliance/images/$IMAGE/$VERSION/summary-$DATE.txt"
      echo "----------------------------------------" >> "compliance/images/$IMAGE/$VERSION/summary-$DATE.txt"
      echo "Critical: $(jq '.Results[].Vulnerabilities[] | select(.Severity=="CRITICAL") | .VulnerabilityID' "compliance/images/$IMAGE/$VERSION/vulnerabilities-$DATE.json" | wc -l)" >> "compliance/images/$IMAGE/$VERSION/summary-$DATE.txt"
      echo "High: $(jq '.Results[].Vulnerabilities[] | select(.Severity=="HIGH") | .VulnerabilityID' "compliance/images/$IMAGE/$VERSION/vulnerabilities-$DATE.json" | wc -l)" >> "compliance/images/$IMAGE/$VERSION/summary-$DATE.txt"
      
  3. Executive Reporting and Dashboards
    • Create security posture dashboards for leadership
    • Track vulnerability trends over time
    • Measure mean time to remediation (MTTR)
    • Generate risk-based reports for different stakeholders
    • Example executive metrics:
      • Total vulnerabilities by severity
      • Vulnerabilities per application/service
      • Average age of open vulnerabilities
      • Patch compliance percentage
      • Trend analysis (week-over-week, month-over-month)
      • Risk exposure score
      

The container security landscape continues to evolve rapidly:

  1. Software Bill of Materials (SBOM)
    • Standardized formats like SPDX and CycloneDX
    • Regulatory requirements for SBOMs (US Executive Order 14028)
    • SBOM as a component of supply chain security
    • Integration with vulnerability management systems
    • Example SBOM generation with Syft:
      # Generate CycloneDX SBOM
      syft packages myapp:latest -o cyclonedx-json > myapp-sbom.json
      
      # Submit to dependency track for continuous monitoring
      curl -X POST "https://dependencytrack.example.com/api/v1/bom" \
        -H "Content-Type: application/json" \
        -H "X-API-Key: $API_KEY" \
        -d @myapp-sbom.json
      
  2. Supply Chain Security
    • Sigstore for keyless signing and transparency logs
    • SLSA (Supply-chain Levels for Software Artifacts) framework
    • Verifiable build provenance
    • Secure artifact metadata
    • Example Cosign image signing:
      # Generate keypair
      cosign generate-key-pair
      
      # Sign container image
      cosign sign --key cosign.key myregistry.io/myapp:latest
      
      # Verify signature
      cosign verify --key cosign.pub myregistry.io/myapp:latest
      
      # Keyless signing with OIDC identity
      cosign sign --identity-token $OIDC_TOKEN myregistry.io/myapp:latest
      
  3. Runtime Security Integration
    • Connecting static analysis with runtime protection
    • Using vulnerability data to inform runtime monitoring
    • Implementing zero-trust approaches for containers
    • Real-time vulnerability exploitation detection
    • Example Falco rule based on CVE knowledge:
      - rule: Exploit_Attempt_CVE_2021_44228
        desc: Detect Log4Shell exploitation attempts
        condition: >
          spawned_process and
          ((proc.name = "java" and proc.args contains "jndi:ldap") or
           (proc.name = "curl" and proc.args contains "jndi:ldap"))
        output: "Log4Shell exploitation attempt (user=%user.name command=%proc.cmdline)"
        priority: CRITICAL
        tags: [CVE-2021-44228, exploitation, MITRE_T1190]
      

Docker image security scanning has evolved from a simple vulnerability check to a comprehensive security discipline that spans the entire container lifecycle. By implementing robust scanning practices, organizations can significantly reduce their security risk, meet compliance requirements, and build trust in their containerized applications. As container adoption continues to grow, security scanning will remain a critical component of any mature container security strategy.

The ability to detect and remediate vulnerabilities before deployment is a key advantage of container-based architectures, making Docker image security scanning not just a security best practice, but a fundamental operational requirement for modern application delivery.