Regex Dos on Docker
How Regex DoS Manifests in Docker
Regular Expression Denial of Service (ReDoS) in Docker environments typically occurs through container build processes, health checks, and runtime configurations that process untrusted input through regex patterns. The vulnerability exploits catastrophic backtracking in poorly constructed regular expressions, causing exponential time complexity that can crash or severely degrade Docker services.
During Docker builds, multistage compilation processes often validate image tags, version strings, or configuration files using regex patterns. Consider a Dockerfile that validates image tags:
FROM alpine:latest
RUN echo "Validating tag format..."
RUN if ! [[ "${TAG}" =~ ^v[0-9]+(?:\.[0-9]+)*$ ]]; then exit 1; fiAn attacker could supply a tag like v1234567890.1234567890.1234567890 with carefully crafted backtracking patterns that cause the regex engine to explore millions of possible matches, consuming CPU resources for seconds or minutes.
Health check configurations in docker-compose.yml files frequently use regex to parse service responses. A common pattern:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
retries: 3
start_period: 30sIf the health check script includes regex validation like:
response=$(curl -s http://localhost:8080/health)
if [[ "$response" =~ ^.*status\s*:\s*ok.*$ ]]; then
exit 0
else
exit 1
fiAn attacker could craft a response with nested patterns that trigger catastrophic backtracking, causing the health check to hang indefinitely and marking healthy services as unhealthy.
Container orchestration platforms like Kubernetes that integrate with Docker registries are also vulnerable. Registry API endpoints that validate image names using regex can be exploited. The Docker Hub API, for instance, might validate image names with patterns like:
^([a-z0-9]+[\.\-_]{0,1})+[a-z0-9]+\/[a-z0-9]+[\.\-_]{0,1}[a-z0-9]+$Attackers can craft image names that cause the regex engine to explore exponential backtracking paths, potentially blocking registry access for legitimate users.
Log processing pipelines within Docker containers often use regex to parse log lines. A typical pattern:
while read -r line; do
if [[ "$line" =~ ^[A-Z]+\s+\[.*\]\s+.*$ ]]; then
echo "Valid log: $line"
fi
doneMalicious log entries with nested bracket patterns can cause the regex to hang, consuming CPU resources and potentially filling disk space if the container cannot process logs fast enough.
Docker-Specific Detection
Detecting ReDoS vulnerabilities in Docker environments requires both static analysis of Docker configurations and dynamic runtime monitoring. The middleBrick API security scanner includes specialized Docker-aware checks that identify regex patterns in Dockerfiles, compose files, and container configurations.
Static analysis begins with scanning Dockerfiles for regex patterns in RUN commands, ENTRYPOINT scripts, and health check configurations. The scanner identifies patterns like:
FROM node:18-alpine
RUN npm install
RUN if [[ "${API_KEY}" =~ ^[A-Za-z0-9]+$ ]]; then echo "Valid"; fi
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1The scanner flags the API key validation regex as potentially vulnerable if it uses naive patterns that don't account for backtracking resistance.
Runtime detection involves monitoring container CPU usage during health checks and build processes. Docker's built-in metrics can reveal suspicious behavior:
docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT
abc123def456 myapp_web_1 350.2% 128MiB / 512MiB
CPU usage spiking to hundreds of percent during health checks indicates potential ReDoS exploitation. The middleBrick scanner actively tests health check endpoints with crafted inputs designed to trigger backtracking in vulnerable regex patterns.
For Docker Compose environments, the scanner analyzes service definitions and their interdependencies. A vulnerable service configuration might look like:
version: '3.8'
services:
api:
build: .
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 5s
retries: 3
environment:
- REGEX_PATTERN=^([a-z]+)+$The scanner identifies the regex pattern in environment variables and tests it with pathological inputs that could cause exponential backtracking.
Registry API endpoints used by Docker clients are also scanned. The middleBrick scanner tests image name validation endpoints with crafted inputs:
curl -X POST http://registry:5000/v2/_catalog
{"repositories": ["valid-image", "malicious-image-a(a+)+b", "another-image"]}The scanner measures response times and flags any endpoint that takes longer than 2 seconds to respond to crafted inputs, indicating potential ReDoS vulnerability.
Docker-Specific Remediation
Remediating ReDoS vulnerabilities in Docker environments requires both code fixes and configuration changes. The most effective approach is replacing vulnerable regex patterns with safe alternatives and implementing runtime protections.
For Dockerfile regex validation, replace naive patterns with atomic grouping or possessive quantifiers where supported. In environments supporting PCRE2, use atomic groups:
FROM alpine:latest
RUN echo "Validating tag format..."
RUN if ! [[ "${TAG}" =~ ^v(?>([0-9]+)\.?)+$ ]]; then exit 1; fiThe (?>(...)) atomic group prevents backtracking within the version number pattern, eliminating the exponential time complexity.
For health check scripts, implement timeout mechanisms and use non-backtracking regex engines:
#!/bin/sh
set -e
response=$(curl -s -m 2 http://localhost:8080/health)
if echo "$response" | grep -q '^[^:]*:[^:]*:'; then
exit 0
else
exit 1
fiThis approach uses grep with simple pattern matching instead of complex regex, and the -m 2 flag limits the request to 2 seconds.
In Docker Compose files, configure health check timeouts to prevent indefinite hangs:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sThe timeout: 10s setting ensures that even if the health check is exploited, it cannot consume resources indefinitely.
For log processing within containers, implement rate limiting and use streaming parsers instead of regex:
#!/bin/sh
while read -r line; do
if printf '%s\n' "$line" | cut -d' ' -f1 | grep -q '^[A-Z][a-z]*$'; then
echo "Valid log: $line"
fi
doneThis approach uses cut and grep with simple patterns instead of complex regex, and processes logs line-by-line to prevent memory exhaustion.
Implement Docker runtime protections using resource limits:
docker run -d --name myapp \
--cpus=".5" \
--memory="256m" \
--health-cmd="curl -f http://localhost:3000/health || exit 1" \
--health-interval="30s" \
--health-timeout="10s" \
--health-retries="3" \
myapp:latestThe --cpus=".5" limit caps CPU usage at 50% of a single core, preventing a single container from consuming all available CPU resources even if exploited.
For registry services, implement input validation at the API layer before regex processing:
function validate_image_name() {
local name="$1"
if [[ "${#name}" -gt 255 ]]; then
return 1
fi
if [[ "$name" =~ [<>:"/\\|?*\x00-\x1F] ]]; then
return 1
fi
return 0
}This pre-validation rejects obviously malicious inputs before they reach more complex regex patterns, providing an early defense layer.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |
Frequently Asked Questions
How can I test my Docker containers for ReDoS vulnerabilities?
middlebrick scan or integrate it into your CI/CD pipeline to catch vulnerabilities before deployment.