Docker security rules are essential for detecting container misconfigurations, privilege escalations, and critical vulnerabilities in Dockerfile and docker-compose.yml files. Code Pathfinder v1.1.1 ships with 47 comprehensive security rules (37 Dockerfile + 10 Docker Compose) that catch issues like Docker socket exposure, root containers, and secret leaks before they reach production.
Why Container Security Matters in the AI Code Generation Era
With AI-powered tools like Claude Code, Windsurf, and GitHub Copilot generating thousands of lines of code in seconds, writing code has become commoditized. Developers can scaffold entire applications, write boilerplate, and implement features at unprecedented speed. The bottleneck has shifted from writing code to reviewing, understanding, and securing code at scale.
Traditional static analysis tools struggle with this new reality. They're designed for human-written code patterns, not AI-generated codebases that mix languages, frameworks, and infrastructure-as-code in the same repository. When your codebase contains Go microservices, Dockerfiles, docker-compose configurations, dependency manifests, and CI pipelines all working together, you need a different approach.
Wait, but aren't Code Pathfinder rules also written by humans? Yes, but here's the key difference: traditional linters hardcode language-specific patterns into their implementation. A Python security linter can't query your Dockerfile. A Dockerfile linter can't trace data flow from your application code. Each tool operates in isolation with brittle regex or AST pattern matching that breaks when code structure changes slightly.
Code Pathfinder flips this model. Rules are written as composable, language-agnostic queries over your codebase's semantic structure. Instead of "find lines matching this regex in Python files," you write "find data flows from HTTP request parameters to shell execution, regardless of whether it happens in Python, the Dockerfile ENTRYPOINT, or docker-compose command overrides." The same query engine works across all languages because code is indexed as structured data, not text files.
This is what I crave as a security engineer: being able to express complex security invariants precisely instead of chaining together brittle grep commands and hoping they catch edge cases. When you're hunting for vulnerabilities or tracking down CVEs, naive regex doesn't cut it. You need to understand control flow, data propagation, and cross-file dependencies.
Code Pathfinder indexes your entire codebase as structured, queryable data. Your code isn't just text to pattern-match. It's parsed into an abstract syntax tree (AST), control flow graph (CFG), and data flow graph (DFG) that you can query like a database. Instead of running separate linters for each language, you write deterministic, cross-language queries that express security invariants across your entire stack:
- Query Go code and Dockerfile commands in a single rule (e.g., "Find Go apps using
os.Setuid(0)that also expose privileged ports in Docker") - Cross-reference code and dependency versions (e.g., "Detect Log4j 2.x usage in Java code where
docker-compose.ymlexposes JMX ports") - Trace data flows across language boundaries (e.g., "User input from Python Flask → shell command in Docker ENTRYPOINT")
This language-agnostic querying is critical for CVE detection and vulnerability research. When a new supply chain vulnerability drops, you don't just need to find the dependency. You need to understand how it's used, what privileges it runs with, and what attack surface it exposes.
That's why Code Pathfinder v1.1.1 includes 47 container security rules as a foundation. These rules demonstrate how to query infrastructure-as-code with the same precision you'd query application code, catching privilege escalations, socket exposures, and misconfigurations before they reach production.
What I'm Shipping
Code Pathfinder v1.1.1 includes comprehensive container security analysis:
37 Dockerfile Rules covering:
- Container Security (4 rules): Privilege escalation, socket exposure, secrets leakage
- Best Practices (28 rules): Image optimization, cache management, reproducible builds
- Correctness (3 rules): Build failures, syntax errors, invalid configurations
- Audit (2 rules): Supply chain security, base image pinning
10 Docker Compose Rules covering:
- Compose Security (10 rules): Privileged containers, capability management, isolation violations
Every rule includes:
- CWE mappings for compliance tracking
- Severity ratings (CRITICAL, HIGH, MEDIUM, LOW)
- Attack scenarios explaining real-world impact
- Secure alternatives with code examples
The Critical Security Issues It Catches
Docker Socket Exposure (CRITICAL)
This is the #1 container escape vector. OWASP's Docker Security Cheat Sheet explicitly warns that exposing the Docker daemon socket is equivalent to granting root on the host. When you mount /var/run/docker.sock into a container, you're giving it full control over the host Docker daemon with unrestricted access. Security researchers at Quarkslab and Dreamlab have documented detailed attack chains showing how this leads to complete host compromise.
Vulnerable Code:
FROM docker:latest # CRITICAL: Exposes Docker socket as volume VOLUME ["/var/run/docker.sock"] CMD ["docker", "ps"]
Attack Chain:
# Step 1: Attacker gains shell in container # Step 2: Create privileged container mounting host root docker run -it -v /:/host --privileged alpine /bin/sh # Step 3: Chroot into host filesystem chroot /host /bin/bash # Step 4: Now has root access - install backdoor echo "* * * * * root /tmp/backdoor.sh" >> /etc/crontab
Code Pathfinder detects this instantly:
@dockerfile_rule( id="DOCKER-SEC-006", severity="CRITICAL", cwe="CWE-250" ) def docker_socket_in_volume(): """Detects Docker socket mounted as volume.""" return any_of( instruction( type="VOLUME", contains="/var/run/docker.sock" ), instruction( type="VOLUME", contains="/run/docker.sock" ) )
Containers Running as Root (HIGH)
Missing USER instructions mean containers run with UID 0 (root). If an attacker compromises the container, they have root privileges, both inside and potentially outside the container.
Vulnerable Code:
FROM node:18 # Missing USER instruction - runs as root! WORKDIR /app COPY . . CMD ["node", "server.js"]
Secure Alternative:
FROM node:18 WORKDIR /app COPY . . # Add non-root user RUN useradd -m -u 1000 appuser && \ chown -R appuser:appuser /app USER appuser # Switch to non-root user CMD ["node", "server.js"]
Secrets in Build Arguments (CRITICAL)
ARG instructions are visible in docker history. Passing secrets via build args leaks them into every layer of the image.
Vulnerable Code:
FROM python:3.11 # CRITICAL: Secret visible in image history ARG DATABASE_PASSWORD ENV DB_PASS=${DATABASE_PASSWORD} RUN pip install psycopg2
What attackers see:
$ docker history myimage:latest IMAGE CREATED BY abc123 ARG DATABASE_PASSWORD=prod_db_p@ssw0rd! # Exposed!
Secure Alternative:
FROM python:3.11 # Use secrets mount (BuildKit) RUN \ export DB_PASS=$(cat /run/secrets/db_password) && \ pip install psycopg2
Privileged Containers in Docker Compose (CRITICAL)
Setting privileged: true disables all container isolation. It's equivalent to running code directly on the host with root privileges.
Vulnerable Code:
version: '3' services: app: image: myapp privileged: true # CRITICAL: Disables all isolation!
Attack Impact:
- Access raw devices (/dev/sda, /dev/mem)
- Load kernel modules
- Modify kernel parameters
- Complete container breakout
How the Python DSL Makes Writing Rules Easy
I designed an intuitive Python DSL that reads like natural language:
from rules.container_decorators import dockerfile_rule from rules.container_matchers import instruction, missing from rules.container_combinators import any_of # Detect missing healthchecks @dockerfile_rule( id="DOCKER-BP-008", severity="MEDIUM" ) def missing_healthcheck(): """Detects Dockerfiles without HEALTHCHECK instruction.""" return missing(instruction="HEALTHCHECK") # Detect latest tags @dockerfile_rule( id="DOCKER-BP-001", severity="MEDIUM" ) def using_latest_tag(): """Detects FROM instructions using :latest tag.""" return instruction( type="FROM", image_tag="latest" ) # Detect package manager cache @dockerfile_rule( id="DOCKER-BP-003", severity="LOW" ) def apt_without_cleanup(): """Detects apt-get install without cleanup.""" return any_of( instruction( type="RUN", contains="apt-get install", not_contains="rm -rf /var/lib/apt/lists" ), instruction( type="RUN", regex=r"apt-get\s+install.*(?<!&& rm)" ) )
No complex AST manipulation. No tree-sitter queries. Just Python.
Coverage: The Complete Rule Set
Dockerfile Rules (37 Total)
| Rule ID | Description | Category | Severity | CWE |
|---|---|---|---|---|
| DOCKER-SEC-001 | Container Running as Root | Security | HIGH | CWE-250 |
| DOCKER-SEC-005 | Secret in Build Argument | Security | CRITICAL | CWE-538 |
| DOCKER-SEC-006 | Docker Socket Mounted as Volume | Security | CRITICAL | CWE-250 |
| DOCKER-SEC-007 | Sudo Usage in Dockerfile | Security | MEDIUM | CWE-250 |
| DOCKER-BP-001 | Base Image Uses :latest Tag | Best Practice | MEDIUM | - |
| DOCKER-BP-003 | Deprecated MAINTAINER Instruction | Best Practice | LOW | - |
| DOCKER-BP-005 | apt-get Without --no-install-recommends | Best Practice | LOW | - |
| DOCKER-BP-006 | Avoid apt-get upgrade | Best Practice | MEDIUM | - |
| DOCKER-BP-007 | apk add Without --no-cache | Best Practice | LOW | - |
| DOCKER-BP-008 | pip install Without --no-cache-dir | Best Practice | LOW | - |
| DOCKER-BP-009 | Avoid dnf update | Best Practice | MEDIUM | - |
| DOCKER-BP-010 | Missing pipefail in Shell Commands | Best Practice | MEDIUM | - |
| DOCKER-BP-011 | Prefer COPY Over ADD | Best Practice | LOW | - |
| DOCKER-BP-012 | Missing yum clean all | Best Practice | LOW | - |
| DOCKER-BP-013 | Missing dnf clean all | Best Practice | LOW | - |
| DOCKER-BP-014 | Remove apt Package Lists | Best Practice | LOW | - |
| DOCKER-BP-015 | Missing Image Version | Best Practice | HIGH | - |
| DOCKER-BP-016 | Prefer JSON Notation for CMD/ENTRYPOINT | Best Practice | LOW | - |
| DOCKER-BP-017 | Use WORKDIR Instead of cd | Best Practice | LOW | - |
| DOCKER-BP-018 | Use Absolute Path in WORKDIR | Best Practice | LOW | - |
| DOCKER-BP-019 | Avoid zypper update | Best Practice | MEDIUM | - |
| DOCKER-BP-020 | Missing zypper clean | Best Practice | LOW | - |
| DOCKER-BP-021 | Missing -y flag for apt-get | Best Practice | LOW | - |
| DOCKER-BP-022 | Missing HEALTHCHECK Instruction | Best Practice | LOW | - |
| DOCKER-BP-023 | Prefer apt-get over apt | Best Practice | LOW | - |
| DOCKER-BP-024 | Install Only One of wget or curl | Best Practice | LOW | - |
| DOCKER-BP-025 | Missing -y flag for yum | Best Practice | LOW | - |
| DOCKER-BP-026 | Missing -y flag for dnf | Best Practice | LOW | - |
| DOCKER-BP-027 | Avoid --platform Flag with FROM | Best Practice | LOW | - |
| DOCKER-BP-028 | Avoid apk upgrade | Best Practice | MEDIUM | - |
| DOCKER-BP-029 | Avoid yum update | Best Practice | MEDIUM | - |
| DOCKER-BP-030 | Nonsensical Command | Best Practice | LOW | - |
| DOCKER-COR-001 | Multiple ENTRYPOINT Instructions | Correctness | MEDIUM | - |
| DOCKER-COR-002 | Invalid Port Number | Correctness | HIGH | - |
| DOCKER-COR-003 | Multiple CMD Instructions | Correctness | MEDIUM | - |
| DOCKER-AUD-001 | Dockerfile Source Not Pinned | Audit | LOW | - |
| DOCKER-AUD-003 | Privileged Port Exposed | Audit | MEDIUM | - |
Docker Compose Rules (10 Total)
| Rule ID | Description | Category | Severity | CWE |
|---|---|---|---|---|
| COMPOSE-SEC-001 | Privileged Container Service | Security | CRITICAL | CWE-250 |
| COMPOSE-SEC-002 | Docker Socket Exposed to Container | Security | CRITICAL | CWE-250 |
| COMPOSE-SEC-003 | Seccomp Confinement Disabled | Security | HIGH | CWE-284 |
| COMPOSE-SEC-006 | Container Filesystem is Writable | Security | LOW | CWE-732 |
| COMPOSE-SEC-007 | Using Host Network Mode | Security | HIGH | CWE-250 |
| COMPOSE-SEC-008 | Dangerous Capability Added | Security | HIGH | CWE-250 |
| COMPOSE-SEC-009 | Using Host PID Mode | Security | HIGH | CWE-250 |
| COMPOSE-SEC-010 | Using Host IPC Mode | Security | MEDIUM | CWE-250 |
| COMPOSE-SEC-011 | Missing no-new-privileges Security Option | Security | MEDIUM | CWE-732 |
| COMPOSE-SEC-012 | SELinux Separation Disabled | Security | MEDIUM | CWE-732 |
Get Started in 30 Seconds
Install Code Pathfinder:
# macOS/Linux brew install shivasurya/tap/pathfinder # Windows choco install code-pathfinder --version=1.1.0
Scan your container configurations:
# Scan all Dockerfiles pathfinder scan --ruleset cpf/docker # Scan docker-compose files pathfinder scan --ruleset cpf/docker-compose # Scan everything pathfinder scan --ruleset cpf/docker --ruleset cpf/docker-compose # CI/CD mode (fails on HIGH+ issues) pathfinder ci --ruleset cpf/docker --severity HIGH
Try It Today
Browse all 47 container security rules in our registry: https://codepathfinder.dev/registry
Key Statistics:
- 47 total rules (37 Docker + 10 Docker Compose)
- 11 CRITICAL severity rules catching container escapes
- 15 CWE mappings for compliance tracking
- Sub-10s scan time for typical projects
- Open source • AGPL-3.0 license
Frequently Asked Questions
What are Docker security rules?
Docker security rules are automated security checks that scan Dockerfiles and docker-compose.yml files for misconfigurations, privilege escalations, and vulnerabilities. They detect issues like exposed Docker sockets (CWE-250), containers running as root, and secrets in build arguments before deployment.
How do Docker security rules prevent container escapes?
Container escapes occur when attackers break out of container isolation to access the host system. Docker security rules detect dangerous configurations like privileged mode, Docker socket mounts (/var/run/docker.sock), and missing USER instructions that enable escape attacks.
What is the most critical Docker security vulnerability?
Docker socket exposure is the #1 container escape vector. Mounting /var/run/docker.sock into a container grants root-level access to the host Docker daemon, allowing attackers to create privileged containers and gain full system control.
How long does it take to scan Docker containers for security issues?
Code Pathfinder scans typical Docker projects in under 10 seconds. The tool analyzes Dockerfiles and docker-compose files using deterministic AST queries, providing instant feedback without false positives.
Can I use Docker security rules in CI/CD pipelines?
Yes. Code Pathfinder integrates into CI/CD workflows with the pathfinder ci command. It fails builds when HIGH or CRITICAL severity issues are detected, preventing vulnerable containers from reaching production.
What's the difference between SAST and runtime container security?
SAST (Static Application Security Testing) analyzes code before deployment to find misconfigurations. Runtime security monitors running containers for suspicious behavior. Code Pathfinder provides SAST for containers, catching issues during development.
Join the Community
I'd love your feedback and contributions:
- Star us on GitHub: github.com/shivasurya/code-pathfinder
- Join discussions: Ask questions, share rules, and discuss container security patterns in GitHub Discussions
- Report issues: Found a false positive or bug? Open an issue
- Contribute rules: Share your container security expertise in Discussions
- Read the docs: codepathfinder.dev/docs
Container security doesn't have to be complicated. With Code Pathfinder, it's just another step in your CI/CD pipeline.
Ship containers confidently. Scan with Code Pathfinder.
Learn more about Docker security best practices from Aqua Security, Better Stack, and Sourcery.