Path Traversal in Flask with Basic Auth
Path Traversal in Flask with Basic Auth — how this specific combination creates or exposes the vulnerability
Path Traversal occurs when an application uses attacker-controlled input to access files outside the intended directory. In Flask, this often arises when a filename or path parameter is directly concatenated into file operations without proper validation or sanitization. Combining this with HTTP Basic Auth can create a misleading sense of security: developers may assume that because an endpoint is protected by authentication, file access is safely constrained. However, authentication and path traversal are independent concerns. Basic Auth protects the endpoint at the HTTP level, but once a request is authenticated, the application may still use user-supplied paths to read or write files. If those paths are not strictly validated, an authenticated attacker can traverse directories using sequences like ../../ to reach sensitive locations such as /etc/passwd or application configuration files.
In a Flask API scanned by middleBrick, unauthenticated attack surface testing can still exercise endpoints that rely on URL parameters or headers for file paths. Even when Basic Auth is present, middleBrick’s checks for Authentication and BOLA/IDOR validate whether authentication is properly enforced and whether access controls correctly scope permissions. Path Traversal findings appear when runtime tests show directory traversal patterns reaching unintended files, regardless of the presence of Basic Auth. This highlights that authentication does not automatically prevent Path Traversal; each endpoint must enforce strict path validation and avoid using user input as direct filesystem paths.
Real-world examples include endpoints that accept a file query parameter to retrieve logs or reports. If the code does not canonicalize or restrict the path, an authenticated user can send a request like /download?file=../../../etc/passwd and potentially read sensitive data. middleBrick’s specification analysis for OpenAPI/Swagger (2.0, 3.0, 3.1) with full $ref resolution can highlight parameters that accept path-like inputs, while runtime checks confirm whether traversal attempts succeed. Findings are reported with severity and remediation guidance, emphasizing input validation, path normalization, and strict allowlists for accessible directories.
Basic Auth-Specific Remediation in Flask — concrete code fixes
To mitigate Path Traversal in Flask when using Basic Auth, you must combine proper authentication with strict input handling. Never trust user-supplied path components. Use a combination of allowlisting, path normalization, and filesystem-safe joins to ensure that authenticated requests cannot escape intended directories.
Secure Basic Auth Pattern in Flask
Below is a concrete, working example of Basic Auth in Flask that avoids common pitfalls. It uses werkzeug.security for password hashing and validates file paths against a configured base directory.
from flask import Flask, request, send_file, jsonify, abort
from werkzeug.security import check_password_hash
import os
app = Flask(__name__)
# Example user store (in production, use a database)
USERS = {
"admin": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"
}
def get_auth():
auth = request.authorization
if not auth or not auth.username or not auth.password:
return None
expected_hash = USERS.get(auth.username)
if expected_hash and check_password_hash(expected_hash, auth.password):
return auth.username
return None
@app.before_request
def require_auth_for_protected_routes():
if request.path.startswith("/protected/"):
if get_auth() is None:
abort(401, description="Authentication required")
@app.route("/protected/download")
def protected_download():
username = get_auth()
if not username:
abort(401, description="Authentication required")
filename = request.args.get("file")
if not filename:
return jsonify({"error": "missing file parameter"}), 400
# Define a strict base directory that is allowed
base_dir = os.path.abspath("/var/app/reports")
# Normalize the user input and join safely
requested_path = os.path.normpath(filename)
full_path = os.path.join(base_dir, requested_path)
# Ensure the resolved path stays within the base directory
try:
common_path = os.path.commonpath([base_dir, full_path])
except ValueError:
return jsonify({"error": "invalid path"}), 400
if common_path != base_dir:
return jsonify({"error": "path traversal not allowed"}), 403
if not os.path.isfile(full_path):
return jsonify({"error": "file not found"}), 404
return send_file(full_path, as_attachment=True)
if __name__ == "__main__":
app.run(debug=False)
This approach ensures that even authenticated requests cannot escape /var/app/reports. The code avoids using raw user input in file operations, instead normalizing and validating the path with os.path.commonpath. In a production deployment, you can further reduce risk by using the middleBrick CLI (middlebrick scan <url>) to verify that your endpoints do not exhibit Path Traversal when exercised with authentication headers.
Additionally, consider using Flask’s send_file with a filename mapping rather than direct user input, and enforce strong password policies for Basic Auth credentials. The middleBrick Pro plan supports continuous monitoring and scans on a configurable schedule, so future changes to file-serving endpoints can be automatically assessed for security regressions.
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
Does Basic Auth alone prevent Path Traversal in Flask APIs?
How can I test my Flask endpoint for Path Traversal while using Basic Auth?
middlebrick scan <url>. Include authentication headers in your requests so the scanner can exercise protected routes and detect directory traversal attempts.