Injection Flaws on Docker
How Injection Flaws Manifests in Docker
Injection flaws in Docker environments exploit the unique characteristics of containerized applications and orchestration systems. Unlike traditional web applications, Docker containers introduce specific attack surfaces where injection vulnerabilities can be particularly dangerous.
The most common Docker-specific injection occurs through docker run commands where user input is passed directly to the Docker daemon. Consider this vulnerable pattern:
docker run -d -p 80:80 --name $USER_INPUT myappAn attacker could set USER_INPUT to web -v /:/host, creating a privileged container with host filesystem access. This allows filesystem traversal and potential privilege escalation beyond the container boundaries.
Docker Compose files present another injection vector. When build arguments or environment variables are interpolated without validation:
version: '3.8'
services:
web:
build:
context: .
args:
- VERSION=$BUILD_VERSION
environment:
- DATABASE_URL=$DB_URLIf BUILD_VERSION or DB_URL contains malicious content, it could lead to arbitrary code execution during the build process or runtime injection attacks.
Dockerfiles themselves can contain injection vulnerabilities through RUN commands that execute shell commands without proper sanitization:
FROM alpine:latest
RUN apk add --no-cache $PACKAGES
COPY . .
RUN npm install $NPM_PACKAGESAn attacker controlling PACKAGES or NPM_PACKAGES could inject additional commands, leading to supply chain attacks or backdoor installation.
Container orchestration platforms like Kubernetes, which work closely with Docker, introduce additional injection surfaces through Helm charts, ConfigMaps, and Secrets that might be improperly validated before deployment.
Docker-Specific Detection
Detecting injection flaws in Docker environments requires specialized scanning that understands container-specific contexts. middleBrick's Docker-aware scanning identifies injection vulnerabilities by examining both the runtime configuration and build-time artifacts.
For command injection in Docker commands, middleBrick analyzes the command structure and flags when user input appears in dangerous positions:
{
"vulnerability": "Command Injection - Docker Run",
"severity": "high",
"description": "User input found in docker run command without validation",
"remediation": "Validate and sanitize all user inputs before passing to Docker commands",
"affected_files": ["docker-compose.yml", "deploy.sh"]
}When scanning Dockerfiles, middleBrick detects dangerous patterns like unvalidated environment variables in RUN commands or ADD/COPY operations that could lead to path traversal:
{
"vulnerability": "Path Traversal in Dockerfile",
"severity": "medium",
"description": "COPY operation uses unvalidated variable that could traverse directories",
"remediation": "Use absolute paths or validate input paths before COPY operations",
"dockerfile_line": 8
}middleBrick's black-box scanning also tests for injection by sending malformed requests to exposed Docker APIs. If the Docker daemon is accessible over the network (a common misconfiguration), it can be vulnerable to remote code execution:
# Vulnerable: Docker API accessible without authentication
curl -X POST http://docker-host:2375/containers/create -d '{"Image":"alpine","Cmd":["/bin/sh","-c","id"]}'The scanner identifies these exposed endpoints and tests for command injection capabilities, flagging any instance where the Docker API responds to unauthenticated requests.
For multi-stage builds, middleBrick checks that build arguments are properly validated and that no sensitive data leaks between stages through injection vulnerabilities.
Docker-Specific Remediation
Remediating injection flaws in Docker environments requires a defense-in-depth approach that addresses both build-time and runtime vulnerabilities. The most effective strategy combines input validation, principle of least privilege, and secure configuration practices.
For Docker commands, always validate and sanitize user inputs before passing them to the Docker CLI:
#!/bin/bash
# Secure pattern: validate container names
function validate_container_name() {
if [[ $1 =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "$1"
else
echo "Invalid container name: $1" >&2
exit 1
fi
}
CONTAINER_NAME=$(validate_container_name "$USER_INPUT")
docker run -d -p 80:80 --name "$CONTAINER_NAME" myappIn Dockerfiles, avoid using unvalidated variables in RUN commands. Instead, use explicit package lists or validate inputs:
FROM alpine:latest
# Secure: explicit package list, no variable interpolation
RUN apk add --no-cache nodejs npm
# If variables must be used, validate them
ARG NPM_PACKAGES
RUN if [[ $NPM_PACKAGES =~ ^[a-zA-Z0-9@\/\-\.\,\s]+$ ]]; then \
npm install $NPM_PACKAGES; \
else \
echo "Invalid packages: $NPM_PACKAGES"; \
exit 1; \
fiFor Docker Compose files, use environment files with strict validation rather than direct variable interpolation:
# .env file with validation
# Only allow specific versions
VALID_VERSIONS="1.0 1.1 1.2"
if [[ ! " $VALID_VERSIONS " =~ " $BUILD_VERSION " ]]; then
echo "Invalid BUILD_VERSION: $BUILD_VERSION" >&2
exit 1
fi
# docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
args:
- VERSION=${BUILD_VERSION}
environment:
- DATABASE_URL=${DB_URL}Network exposure of the Docker daemon should be eliminated. Use Unix sockets instead of TCP ports:
# Secure: Docker daemon only accessible via Unix socket
systemctl edit docker.service
# Add: ExecStart=...
# Remove: -H fd:// -H tcp://0.0.0.0:2375Implement user namespace remapping to prevent container-to-host privilege escalation:
# /etc/docker/daemon.json
{
"userns-remap": "default"
}For CI/CD pipelines that build Docker images, use Kaniko or BuildKit in unprivileged mode rather than allowing Docker-in-Docker patterns that could be exploited for injection attacks.