Back to blog

Over 10,000 Docker Hub Images Leaking Credentials: What You Need to Know

Hello HaWkers, a concerning discovery is shaking the DevOps community. Security researchers have identified over 10,000 public images on Docker Hub that are leaking credentials, API keys, access tokens, and other sensitive information.

If you use Docker containers in production, this article is essential to understand the problem and how to protect yourself. The issue goes beyond a simple technical flaw: it exposes insecure practices that are widespread throughout the industry.

The Discovery and Its Dimensions

Security researchers conducted a massive analysis of Docker Hub, scanning thousands of public images for exposed secrets. The result was alarming.

Key Numbers:

  • Over 10,000 images with exposed credentials
  • AWS keys, GitHub tokens, database passwords
  • Private TLS certificates and SSH keys
  • Cloud service API tokens
  • Third-party service credentials (Stripe, Twilio, SendGrid)

🚨 Alert: Many of these images are downloaded thousands of times per week, meaning the exposed credentials may be in use in production environments around the world.

How Credentials End Up in Images

Understanding how this happens is crucial to preventing the problem in your own images. There are several common ways secrets end up exposed in containers.

Common Leak Scenarios

1. Environment Variables in Build:

Developers frequently pass credentials as environment variables during the build, without realizing they are recorded in the image layers.

# WRONG - Credential stays in the image
FROM node:18
ENV DATABASE_URL=postgres://user:password@host:5432/db
COPY . .
RUN npm install

2. Copied Configuration Files:

Files like .env, config.json or cloud provider credentials are accidentally copied to the image.

# WRONG - Copies everything, including .env
FROM node:18
WORKDIR /app
COPY . .
RUN npm install

3. Layer History:

Even if you delete a file in a later layer, it still exists in the previous image layers.

# WRONG - The file still exists in the layers
FROM node:18
COPY secrets.json /app/
RUN rm /app/secrets.json

How to Check Your Own Images

Now that you understand the problem, it's time to audit your Docker images. There are specific tools for this task.

Secret Analysis Tools

1. Trivy (Aqua Security):

# Scan local image
trivy image --scanners secret my-image:latest

# Scan Docker Hub image
trivy image --scanners secret user/image:tag

2. Docker Scout:

# Analyze vulnerabilities and secrets
docker scout cves my-image:latest
docker scout quickview my-image:latest

3. Dockle:

# Check best practices
dockle my-image:latest

Manual Layer Analysis

You can also inspect layers manually to understand what is in each one:

# Save image as tar
docker save my-image:latest > image.tar

# Extract and analyze
mkdir analysis && tar -xf image.tar -C analysis

# Check layer contents
for layer in analysis/*/layer.tar; do
  echo "=== $layer ==="
  tar -tf "$layer" | grep -E '\.(env|json|key|pem|conf)$'
done

Best Practices to Avoid Leaks

Prevention is always better than cure. Here are the best practices to keep your Docker images secure.

1. Use Build Secrets (Docker BuildKit)

# syntax=docker/dockerfile:1.4
FROM node:18

# Use secret during build without exposing in image
RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN=$(cat /run/secrets/npm_token) \
    npm install
# Build with secret
docker build --secret id=npm_token,src=./.npmrc -t app:latest .

2. Multi-Stage Builds

# Stage 1: Build with dependencies
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
# Credentials only exist in this stage
ARG NPM_TOKEN
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Clean final image
FROM node:18-slim
WORKDIR /app
# Copy only necessary artifacts
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]

3. Robust .dockerignore File

# Ignore sensitive files
.env
.env.*
*.pem
*.key
.aws/
.ssh/
credentials.json
secrets/
*.secret

# Ignore development files
.git
node_modules
.vscode
*.log

4. Runtime Secret Injection

# docker-compose.yml
version: '3.8'
services:
  app:
    image: my-app:latest
    secrets:
      - db_password
      - api_key
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    external: true

The Impact on the Industry

This discovery raises important questions about software supply chain security.

Identified Risks

Infrastructure Access:

  • AWS keys allow access to cloud resources
  • Database credentials expose sensitive data
  • CI/CD tokens allow malicious code injection

Lateral Movement:

  • One leaked credential can lead to others
  • Access to private repositories
  • Compromise of entire pipelines

Financial Impact:

  • Unauthorized use of cloud resources
  • Incident response costs
  • Potential regulatory fines (GDPR, CCPA)

What Companies Are Doing

Company Action Taken
Docker Implementing automatic scanning
AWS Alerts for publicly exposed keys
GitHub Secret scanning in repositories
Google Cloud Credential detection in logs

Prevention Tools in CI/CD

To prevent credentials from reaching images, implement checks in the CI/CD pipeline.

GitHub Actions

name: Security Scan
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build Image
        run: docker build -t app:${{ github.sha }} .

      - name: Trivy Scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'app:${{ github.sha }}'
          format: 'sarif'
          output: 'trivy-results.sarif'
          scanners: 'vuln,secret'

      - name: Upload Results
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: 'trivy-results.sarif'

Pre-commit Hooks

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks

  - repo: https://github.com/trufflesecurity/trufflehog
    rev: v3.63.0
    hooks:
      - id: trufflehog

What to Do If Your Credentials Were Exposed

If you discover that credentials were exposed in a Docker image, act immediately.

Response Steps:

  1. Rotate Credentials: Generate new credentials immediately
  2. Audit Usage: Check access logs for unauthorized use
  3. Remove Image: Delete the image from Docker Hub
  4. Notify: Inform relevant teams and stakeholders
  5. Document: Record the incident for later analysis

⚠️ Important: Just removing the image is not enough. If someone already downloaded the image, the credentials remain exposed. Rotation is mandatory.

Conclusion

The leak of over 10,000 Docker images with exposed credentials is a reminder that security needs to be an integral part of the development process, not an afterthought. The good news is that the tools and practices to prevent this are available and relatively simple to implement.

If you work with containers, take time to audit your images and implement the best practices recommended in this article. The security of your environment depends on it.

If you are interested in security in development, I recommend checking out another article: Critical Vulnerability in React Server Components: What You Need to Know to Protect Your Applications where you will discover how to protect your React applications against recent vulnerabilities.

Let's go! 🦅

Comments (0)

This article has no comments yet 😢. Be the first! 🚀🦅

Add comments