HIGH container escapeapi keys

Container Escape with Api Keys

How Container Escape Manifests in API Keys

Container escape vulnerabilities combined with poorly protected API keys create a critical attack chain. An attacker who escapes a container can access host-level secrets or other container secrets if API keys are stored insecurely. Common manifestation patterns include:

  • Mounted Host Directories: API keys stored in files on the host (e.g., /etc/secrets/api_key.txt) are mounted into containers via Docker -v or Kubernetes hostPath volumes. If the container runs with excessive privileges (e.g., --privileged), an attacker can traverse out of the container to read the host file directly.
  • Docker Socket Binding: Mounting /var/run/docker.sock into a container (-v /var/run/docker.sock:/var/run/docker.sock) allows container processes to control the Docker daemon. An attacker can launch a new container with the host's secret directory mounted, exfiltrating API keys.
  • Kubernetes Secret Misconfiguration: Kubernetes Secrets mounted as volumes (secretKeyRef) are accessible at /var/run/secrets/kubernetes.io/serviceaccount/ within the container. If the container runs as root (common in misconfigured pods) or with a hostPath mount pointing to the secret's etcd storage location, escape can lead to direct secret theft.
  • Shared Kernel Namespaces: Containers sharing the host's PID, network, or mount namespaces (e.g., --pid=host) can enumerate processes or mount points on the host, locating API keys stored in environment variables or temporary files.

For example, a vulnerable Docker run command might expose API keys:

docker run -d \
  -v /host/secrets:/container/secrets \
  -e API_KEY=$(cat /host/secrets/key.txt) \
  --privileged \
  vulnerable-app:latest

Here, the --privileged flag grants the container nearly all host capabilities. If the application has a container escape flaw (e.g., a kernel vulnerability like CVE-2019-5736), the attacker can read /host/secrets/key.txt directly from the host filesystem.

API Keys-Specific Detection

Detecting this issue requires correlating container configuration weaknesses with API key exposure. Manual inspection involves reviewing Dockerfiles, Kubernetes manifests, and cloud configuration for risky patterns:

  • Look for hostPath volumes in Kubernetes that mount sensitive directories (/etc/secrets, /var/run/secrets) into containers.
  • Check Docker run commands or Compose files for -v mounts pointing to host secret locations and --privileged or --cap-add=SYS_ADMIN flags.
  • Verify container user settings (USER in Dockerfile, securityContext.runAsUser in Kubernetes) to ensure non-root execution.

Scanning with middleBrick identifies exposed API keys at the runtime layer. When you scan an API endpoint, middleBrick tests for:

  • Hardcoded Keys in Responses: Regex patterns matching common API key formats (e.g., sk_live_... for Stripe, AIza... for Google) in error messages, JSON responses, or headers.
  • Environment Variable Leakage: Some frameworks (e.g., older Express.js setups) may dump environment variables in stack traces. middleBrick probes for this by triggering errors.
  • Metadata Endpoint Exposure: Cloud provider metadata services (e.g., AWS EC2 http://169.254.169.254/) sometimes contain IAM credentials that can be used to access secret managers. If an API inadvertently proxies or reveals these, it's flagged.

While middleBrick cannot directly see container configurations (black-box scanning), it detects the symptom: API keys that should be secret are exposed via the API. This indicates a broader secret management failure that may include container-related risks. For instance, a finding of "API Key in Error Response" suggests the key might be stored in an environment variable that could be accessible via container escape if the host's secret management is similarly flawed.

Example CLI scan to detect exposed keys:

middlebrick scan https://api.example.com/v1/users

The report will highlight any exposed keys under "Data Exposure" or "Authentication" categories, with severity based on key sensitivity (e.g., cloud provider keys are critical).

API Keys-Specific Remediation

Remediation focuses on secret management principles that mitigate both API key exposure and container escape risks. Use native features of your container platform and application framework:

  • Never Store Secrets in Files Mounted from Host: Instead, use platform-managed secrets. For Docker Swarm, use docker secret; for Kubernetes, use Secret objects mounted as volumes or environment variables with strict RBAC.
  • Avoid Privileged Containers: Drop capabilities and run as non-root. In Docker, use --cap-drop=ALL and --security-opt=no-new-privileges. In Kubernetes, set securityContext.runAsNonRoot: true and allowPrivilegeEscalation: false.
  • Use Ephemeral Secrets: Fetch API keys at runtime from a secrets manager (e.g., HashiCorp Vault, AWS Secrets Manager) using IAM roles assigned to the container/pod. This avoids storing keys on disk.

Code Fix Example (Node.js with Docker/Kubernetes):

Vulnerable: Reading a key from a mounted file and setting it as an env var.

// vulnerable-app.js
const fs = require('fs');
const apiKey = fs.readFileSync('/secrets/api_key.txt', 'utf8'); // File mounted from host
process.env.STRIPE_API_KEY = apiKey;

// Later, used in code
const stripe = require('stripe')(process.env.STRIPE_API_KEY);

Remediated: Using Kubernetes Secrets as environment variables (declared in manifest) and ensuring the container runs as non-root.

// remediated-app.js
// Key is injected by Kubernetes as env var, not read from file
const stripe = require('stripe')(process.env.STRIPE_API_KEY);

Kubernetes manifest snippet:

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  containers:
  - name: app
    image: secure-app:latest
    env:
    - name: STRIPE_API_KEY
      valueFrom:
        secretKeyRef:
          name: stripe-secret
          key: api-key
    securityContext:
      runAsNonRoot: true
      runAsUser: 1000
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]

For Docker without orchestration, use Docker secrets with a minimal container user:

# Dockerfile
FROM node:18-alpine
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs
COPY --chown=nodejs:nodejs . .
CMD ["node", "app.js"]
# docker-compose.yml
version: '3.8'
services:
  app:
    image: secure-app:latest
    secrets:
      - stripe_api_key
    environment:
      STRIPE_API_KEY_FILE: /run/secrets/stripe_api_key
secrets:
  stripe_api_key:
    external: true

The application reads the key from the file path provided by Docker, which is managed securely by the Docker daemon and not directly mounted from the host filesystem.

Finally, implement runtime monitoring. middleBrick's Pro plan includes continuous monitoring to alert if API keys become exposed again, and its GitHub Action can fail deployments if new findings appear, preventing vulnerable configurations from reaching production.

Frequently Asked Questions

Can middleBrick detect if my container configuration allows secret theft via escape?
No. middleBrick is a black-box scanner that tests your API endpoint over the network. It cannot see inside your containers or orchestration layer. However, it will detect if API keys are exposed through the API itself (e.g., in error messages or responses), which is a strong indicator that your secret management—including container-related storage—is inadequate. You must separately audit container configurations using tools like Docker Bench for Security or kube-score.
Is storing API keys in environment variables inside containers safe from container escape?
Environment variables are safer than files but not immune. If a container escapes and gains host PID namespace access, it may read environment variables of other processes on the host. Additionally, environment variables can be leaked via core dumps or debugging tools. The safest approach is to use short-lived, dynamically fetched credentials from a secrets manager (like Vault) with strict pod identity policies, and to run containers with minimal privileges and non-root users.