Bleichenbacher Attack on Docker
How Bleichenbacher Attack Manifests in Docker
The Bleichenbacher attack exploits RSA PKCS#1 v1.5 padding oracle vulnerabilities, and in Docker environments, this manifests through several specific attack patterns that target containerized applications.
When Docker containers expose TLS/SSL endpoints using vulnerable OpenSSL libraries, attackers can exploit timing differences in padding validation responses. A typical scenario involves a containerized API service that uses RSA encryption for key exchange during TLS handshakes. If the container runs an outdated OpenSSL version (pre-1.1.0), the PKCS#1 v1.5 padding validation is vulnerable to timing attacks.
Consider a Dockerized microservice using Python's cryptography library with RSA encryption:
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
# Vulnerable RSA encryption in a Docker container
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
# PKCS#1 v1.5 padding - vulnerable to Bleichenbacher
ciphertext = public_key.encrypt(
b"Sensitive data",
padding.PKCS1v15()
)
In Docker environments, this vulnerability becomes particularly dangerous because:
- Containers often share the same host kernel, allowing attackers to observe timing differences across containers
- Auto-scaling and ephemeral containers create inconsistent patching states
- Multi-stage Docker builds might include vulnerable base images without updating dependencies
A real-world attack scenario: An attacker sends crafted ciphertexts to a Dockerized API endpoint and observes response timing. By measuring the time difference between valid and invalid padding responses, they can gradually decrypt the original message without knowing the private key.
Docker-Specific Detection
Detecting Bleichenbacher vulnerabilities in Docker requires examining both the container runtime and application code. Here's how to identify this issue in your Docker environment:
1. Base Image Analysis
Check your Dockerfile for vulnerable base images:
# Vulnerable - uses outdated OpenSSL
FROM python:3.7-slim
# Secure - uses updated libraries
FROM python:3.9-slim-buster
2. Dependency Scanning
Use dependency scanners to check for vulnerable OpenSSL versions:
# Check OpenSSL version in running container
docker exec <container_id> openssl version
# Example output to watch for:
# OpenSSL 1.0.2u 20 Dec 2019 (vulnerable)
# OpenSSL 1.1.1k 25 Mar 2021 (secure)
3. middleBrick API Security Scanning
middleBrick provides Docker-specific detection by scanning exposed API endpoints for padding oracle vulnerabilities:
# Scan your Dockerized API with middleBrick
middlebrick scan https://api.yourdockerapp.com
# Output includes:
# - Bleichenbacher padding oracle detection
# - Timing analysis results
# - Severity scoring (A-F) for this vulnerability
4. Runtime Monitoring
Monitor for suspicious timing patterns in your Docker containers:
# Monitor TLS handshake timing
docker run --name monitor -d alpine tail -f /dev/null
docker exec monitor apk add --no-cache openssl
docker exec monitor time openssl s_client -connect api.yourdockerapp.com:443
5. Configuration Validation
Check your Docker Compose or Kubernetes manifests for security configurations:
# docker-compose.yml example
version: '3.8'
services:
api:
image: your-api:latest
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
environment:
- OPENSSL_CONF=/etc/ssl/openssl.cnf
Docker-Specific Remediation
Remediating Bleichenbacher vulnerabilities in Docker requires both code changes and infrastructure updates. Here are Docker-specific solutions:
1. Update Base Images and Dependencies
The most critical fix is using updated base images with patched OpenSSL:
# Multi-stage build with security updates
FROM python:3.9-slim-buster AS base
RUN apt-get update && apt-get install -y \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
FROM base AS builder
# Install cryptography with updated OpenSSL
RUN pip install --no-cache-dir cryptography
FROM base
COPY --from=builder /usr/local/lib/python3.9/site-packages/cryptography /usr/local/lib/python3.9/site-packages/cryptography
2. Use OAEP Padding Instead of PKCS#1 v1.5
Modify your application code to use secure padding:
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
# Secure RSA encryption using OAEP padding
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
# OAEP padding - resistant to Bleichenbacher attack
ciphertext = public_key.encrypt(
b"Sensitive data",
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
3. Implement Constant-Time Validation
Add constant-time validation to prevent timing attacks:
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
import hmac
import time
def constant_time_compare(val1, val2):
"""Prevent timing attacks by using constant-time comparison"""
return hmac.compare_digest(val1, val2)
def secure_decrypt(private_key, ciphertext):
try:
# Add artificial delay to mask timing differences
start_time = time.time()
plaintext = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# Constant-time delay to prevent timing analysis
elapsed = time.time() - start_time
time.sleep(max(0, 0.1 - elapsed)) # 100ms minimum processing time
return plaintext
except Exception:
# Always return in constant time
time.sleep(0.1)
return None
4. Docker Security Hardening
Add security configurations to your Docker setup:
# docker-compose.yml with security hardening
version: '3.8'
services:
api:
build: .
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
read_only: true
tmpfs:
- /tmp:rw,noexec,nosuid,size=100m
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
5. Automated Scanning with middleBrick
Integrate middleBrick into your Docker CI/CD pipeline:
# .github/workflows/docker-security.yml
name: Docker Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t your-app:security .
- name: Run middleBrick scan
run: |
npm install -g middlebrick
middlebrick scan https://api.yourdockerapp.com \
--output json \
--fail-below B
env:
MIDDLEBRICK_API_KEY: ${{ secrets.MIDDLEBRICK_API_KEY }}
- name: Security assessment
run: |
docker run --rm -v $(pwd):/app your-app:security python -c "
import os
print('Base image:', os.popen('cat /etc/os-release').read())
print('OpenSSL version:', os.popen('openssl version').read())
"
Frequently Asked Questions
How can I test if my Dockerized API is vulnerable to Bleichenbacher attacks?
Use middleBrick to scan your API endpoints - it specifically tests for padding oracle vulnerabilities including Bleichenbacher attacks. You can also manually test by checking your OpenSSL version in running containers and verifying that your application uses OAEP padding instead of PKCS#1 v1.5. Look for timing inconsistencies in TLS handshake responses as another indicator.
Does using HTTPS in my Docker containers protect against Bleichenbacher attacks?
No, HTTPS alone does not protect against Bleichenbacher attacks. The vulnerability exists in the RSA encryption implementation used during TLS handshakes, regardless of whether the connection is encrypted. You need to ensure your containers use updated OpenSSL libraries (1.1.0+) and that your application code uses secure padding schemes like OAEP instead of the vulnerable PKCS#1 v1.5 padding.