HIGH container escapeflaskpython

Container Escape in Flask (Python)

Container Escape in Flask with Python — how this specific combination creates or exposes the vulnerability

Flask applications running inside containers are often exposed to network requests that can trigger unintended behavior if the application mishandles user input. A container escape occurs when an attacker breaks out of the container’s isolated filesystem and gains access to the host system or other containers. In Flask, this risk is amplified when the application uses Python’s subprocess, os.system, or file operation functions with unsanitized user input, especially if the container runs with elevated privileges or mounts host directories.

For example, a Flask endpoint that accepts a filename parameter and uses it directly in a shell command without validation can lead to command injection. If the container has access to the host’s /proc, /sys, or Docker socket (/var/run/docker.sock), an attacker can escalate to host-level access. Real-world parallels include CVE-2019-5736 (runc) and CVE-2021-22555 (Linux kernel), where container misconfigurations allowed host compromise.

middleBrick detects such risks by scanning for unauthenticated endpoints that reflect user input into dangerous functions. It checks for patterns like direct use of user input in subprocess.call(), eval(), or file paths without sanitization — common in Flask apps that serve files, execute scripts, or process uploads. The scanner maps findings to OWASP API Top 10 (e.g., A1:2023 Broken Object Level Authorization, A3:2023 Injection) and provides severity-scored guidance.

Python-Specific Remediation in Flask — concrete code fixes

To prevent container escape vectors in Flask, avoid passing user input directly to shell commands or file operations. Use Flask’s built-in request handling, validate and sanitize all inputs, and leverage safe APIs. Never use shell=True in subprocess with user data. Instead, use argument lists and restrict operations to predefined, safe directories.

The following Flask code shows a vulnerable file-read endpoint:

from flask import Flask, request, abort
import subprocess

app = Flask(__name__)

@app.route('/read')
def read_file():
    filename = request.args.get('file', '')
    # VULNERABLE: direct use of user input in shell command
    output = subprocess.check_output(f'cat /app/files/{filename}', shell=True)
    return output.decode('utf-8')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

This is dangerous because an attacker could request ?file=../../etc/passwd or ?file=id; rm -rf /. The fix removes shell usage, validates the filename against a safe list, and uses os.path to prevent path traversal:

from flask import Flask, request, abort
import os

app = Flask(__name__)
BASE_DIR = '/app/files'

@app.route('/read')
def read_file():
    filename = request.args.get('file', '')
    if not filename:
        abort(400, 'Missing file parameter')
    # Prevent path traversal
    filename = os.path.basename(filename)
    safe_path = os.path.join(BASE_DIR, filename)
    # Ensure the path stays within BASE_DIR
    if not os.path.commonpath([BASE_DIR, safe_path]) == BASE_DIR:
        abort(403, 'Access denied')
    try:
        with open(safe_path, 'r') as f:
            content = f.read()
        return content
    except FileNotFoundError:
        abort(404, 'File not found')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Additional protections: run the container as a non-root user, drop unnecessary capabilities (--cap-drop ALL), and avoid mounting the Docker socket or host filesystems unless absolutely required. middleBrick flags the original version as high-risk under Injection and Data Exposure categories, with remediation guidance aligned to CWE-78 (OS Command Injection) and CWE-22 (Path Traversal).

Frequently Asked Questions

Can middleBrick detect container escape risks in Flask apps without seeing the source code?
Yes. middleBrick performs black-box scanning by sending crafted requests to unauthenticated endpoints. It identifies dangerous patterns like reflected user input in file paths or command execution vectors, even without source access. For example, if a Flask endpoint returns different responses based on ../../ payloads or executes commands via user input, middleBrick flags it as a potential injection or path traversal risk.
Does using Flask’s built-in development server increase container escape risk?
The development server (flask run) is not meant for production and lacks security hardening, but the container escape risk stems from application logic and container configuration — not the server itself. However, running any Flask app as root inside a container with host mounts increases impact. middleBrick does not assess the server choice but scans for exploitable endpoints regardless of whether you use app.run(), Gunicorn, or uWSGI.