HIGH information disclosuredocker

Information Disclosure on Docker

How Information Disclosure Manifests in Docker

Information disclosure in Docker environments occurs through several unique attack vectors that stem from the containerization architecture itself. Unlike traditional web applications, Docker's layered filesystem, privileged execution contexts, and network exposure patterns create specific disclosure opportunities that developers must understand.

One of the most common Docker-specific information disclosure patterns involves /proc filesystem exposure. When containers run with --privileged or mount /proc with excessive permissions, attackers can read sensitive runtime information. Consider this vulnerable Dockerfile:

FROM node:18-alpine
RUN apk add --no-cache procps

# Dangerous: exposes system information
RUN echo 'export PS1="Docker:\w$ "' >> /root/.bashrc
EXPOSE 3000

# Container may expose /proc to host processes
VOLUME ["/proc"]

CMD ["node", "server.js"]

This configuration allows processes within the container to read host system information through /proc mounts, potentially exposing kernel parameters, memory usage, and running processes from the host system.

Another critical disclosure vector is Docker daemon API exposure. When the Docker daemon listens on TCP sockets without authentication, attackers can enumerate all containers, images, and volumes. The following configuration is vulnerable:

# DOCKER_HOST=unix:///var/run/docker.sock
# Vulnerable: daemon listening on all interfaces without auth
DOCKER_OPTS="-H tcp://0.0.0.0:2375"

# Secure alternative: require TLS
DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem"

Without TLS verification, any network-connected attacker can run docker -H tcp://host:2375 info to retrieve comprehensive system information including kernel version, total memory, and available storage.

Environment variable leakage represents another Docker-specific disclosure pattern. When Docker secrets or configuration variables are passed to containers without proper scoping, they become accessible to all processes. This vulnerable pattern:

# .env file with sensitive data
DATABASE_URL=postgresql://user:pass@db:5432/dbname
API_KEY=sk-1234567890abcdef

# Docker-compose exposes all variables
version: '3.8'
services:
  app:
    build: .
    env_file: .env
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production

Creates a situation where any process inside the container can read these variables, and if the container is compromised, the attacker gains immediate access to database credentials and API keys.

Docker image layer analysis also enables information disclosure. Each layer in a Docker image preserves historical data, including deleted files that may contain sensitive information. Consider this insecure build pattern:

FROM ubuntu:20.04

# Layer 1: Copy sensitive credentials
COPY .env /app/

# Layer 2: Delete the file
RUN rm /app/.env

# Layer 3: Copy application code
COPY . /app/

# The .env file still exists in Layer 1 and can be extracted
CMD ["node", "/app/server.js"]

Even though .env is deleted in the final image, it remains accessible in the image history. Attackers can extract previous layers using docker history or specialized tools, recovering deleted credentials.

Docker-Specific Detection

Detecting information disclosure vulnerabilities in Docker requires specialized scanning approaches that understand container-specific attack surfaces. Traditional web application scanners miss Docker-specific issues like daemon exposure, layer analysis, and container escape vectors.

middleBrick's Docker-aware scanning identifies these unique disclosure patterns through its black-box approach. When you scan a Docker-deployed API endpoint, middleBrick tests for:

Docker Daemon Exposure: The scanner attempts to connect to common Docker daemon ports (2375 for HTTP, 2376 for HTTPS) and verifies authentication requirements. It tests for the absence of TLS verification and attempts to enumerate container information through unauthenticated endpoints.

Environment Variable Leakage: middleBrick analyzes HTTP responses for patterns matching Docker environment variable formats, including DATABASE_URL, API_KEY, SECRET_*, and framework-specific variables like NODE_ENV or FLASK_ENV. The scanner also tests for verbose error messages that might reveal Docker-specific configuration details.

Layer Analysis Vulnerabilities: While middleBrick cannot directly inspect image layers through black-box scanning, it identifies indicators of poor build practices through runtime behavior. The scanner looks for timing attacks, error messages that reveal build paths, and response headers that might indicate containerized environments.

Network Exposure Patterns: middleBrick tests for Docker's default bridge network exposure, where containers might be accessible on the host network without proper firewall rules. It attempts to discover internal container IPs and test for services listening on Docker's default bridge range (172.17.0.0/16).

Using middleBrick's CLI for Docker-specific scanning:

# Scan a Docker-deployed API
npm install -g middlebrick
middlebrick scan https://api.example.com --output json

# Scan multiple endpoints from a Docker Compose setup
middlebrick scan --targets file:docker-endpoints.txt --output html

# Integrate with GitHub Actions for Docker deployments
- name: Run middleBrick Scan
  uses: middlebrick/middlebrick-action@v1
  with:
    target: https://staging-api.company.com
    fail-on-severity: high
    output-format: json

The scanner's 12 parallel security checks include Docker-specific patterns like authentication bypass attempts that exploit container escape vulnerabilities and input validation tests that target Docker's command injection surfaces.

Docker-Specific Remediation

Remediating Docker information disclosure vulnerabilities requires implementing Docker-native security controls and following container security best practices. These solutions leverage Docker's built-in features to eliminate disclosure vectors.

Secure Docker Daemon Configuration: The foundation of Docker security is proper daemon configuration. Implement TLS authentication and bind to specific interfaces:

# Create CA and certificates
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem

# Create server key and certificate
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=server" -sha256 -new -key server-key.pem -out server.csr
echo subjectAltName = DNS:server,IP:192.168.1.100,IP:127.0.0.1 >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.pem -extfile extfile.cnf

# Create client certificates
openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile-client.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem -extfile extfile-client.cnf

# Configure Docker daemon
DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem"

This configuration ensures that only authenticated clients with valid certificates can interact with the Docker daemon, eliminating unauthenticated information disclosure.

Secure Build Practices: Implement multi-stage builds and secret management to prevent layer-based disclosure:

# Multi-stage build with secrets
FROM node:18-alpine AS builder

# Use build arguments for secrets (not environment variables)
ARG NPM_TOKEN
RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
COPY package*.json ./
RUN npm ci --only=production

# Secure final stage
FROM node:18-alpine AS production

# Copy only necessary files
COPY --from=builder /app/node_modules ./node_modules
COPY . .

# Remove build artifacts and secrets
RUN rm -f .npmrc package-lock.json

# Use non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs

EXPOSE 3000
CMD ["node", "server.js"]

Build this image with: docker build --build-arg NPM_TOKEN=$NPM_TOKEN -t secure-app .

Environment Variable Security: Use Docker secrets and proper variable scoping:

# docker-compose.yml with secrets
version: '3.8'
services:
  app:
    build: .
    secrets:
      - db_password
      - api_key
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:${DB_PASSWORD}@db:5432/dbname
    ports:
      - "3000:3000"

secrets:
  db_password:
    external: true
  api_key:
    external: true

Store secrets in Docker's secret management system rather than passing them as plain environment variables.

Network Isolation: Configure proper network segmentation to prevent Docker bridge exposure:

# Create isolated network
docker network create --driver bridge --subnet 192.168.10.0/24 --gateway 192.168.10.1 secure-net

# Run containers with specific network
docker run -d --network secure-net --ip 192.168.10.10 --name secure-app secure-app-image

# Remove default bridge access
iptables -I DOCKER-USER -i docker0 -j DROP
iptables -I DOCKER-USER -i docker0 -s 192.168.10.0/24 -j ACCEPT

These configurations eliminate the most common Docker information disclosure vectors while maintaining application functionality.

Frequently Asked Questions

Can middleBrick scan Docker images directly for information disclosure?
middleBrick performs black-box scanning of running API endpoints, not static image analysis. It tests the runtime behavior of Docker-deployed applications to identify information disclosure through network exposure, authentication bypasses, and response analysis. For image layer analysis, you would need to combine middleBrick with container-specific tools like Dockle or Hadolint.
How does Docker's default configuration contribute to information disclosure?
Docker's default configuration exposes several information disclosure vectors: the daemon listens on a Unix socket accessible to root users, containers share the host's network namespace by default in some configurations, and build layers preserve historical data. The default bridge network (172.17.0.0/16) also allows containers to discover each other's IPs, potentially exposing internal services. Proper Docker security requires explicit configuration changes to eliminate these default disclosure patterns.