Symlink Attack in Flask with Bearer Tokens
Symlink Attack in Flask with Bearer Tokens — how this specific combination creates or exposes the vulnerability
A symlink attack in Flask involving Bearer tokens occurs when an API endpoint that serves files or writes files on the server uses user-controlled input to determine file paths without adequate validation. If the endpoint also relies on Bearer token authentication for access control, an attacker may exploit path traversal or insecure temporary file creation to place a symlink that redirects writes to a sensitive location, such as a file expected to be read by an authenticated service using the Bearer token. For example, an endpoint that accepts a filename parameter and saves it under a directory determined by the authenticated user could allow an authenticated user to supply a path like ../../../secrets/token_store.txt, causing the application to overwrite or create files outside the intended directory. The presence of Bearer tokens does not inherently protect file operations; it only identifies the requesting principal. If authorization checks do not validate the final resolved path, the token can be abused to gain unintended access to or manipulate files that the token should not affect, leading to information disclosure or privilege escalation.
In a black-box scan, middleBrick tests such unauthenticated and authenticated attack surfaces by submitting path manipulation inputs and observing whether the resolved target can be redirected. When combined with Bearer tokens used for authentication, the scanner checks whether authorization boundaries are respected across path resolution and file operations. Real-world patterns include missing canonicalization before file access, use of user data in temporary file names, and insecure default configurations that allow symlink races. A concrete scenario: an API that accepts an upload and stores it under a user-specific folder identified by a Bearer token may be tricked into writing a symlink to a system file if the filename is not sanitized, causing the application to follow the symlink on subsequent reads and expose or alter data associated with that token.
Because this involves unauthenticated attack surface testing, middleBrick can probe endpoints that require Bearer tokens by attempting path traversal and inclusion techniques to see if authorization is bypassed at the filesystem level. The scanner does not modify files or tokens; it reports whether resolution can be directed outside intended directories and provides remediation guidance to ensure path validation occurs independently of token-based identity checks.
Bearer Tokens-Specific Remediation in Flask — concrete code fixes
To remediate symlink risks when using Bearer tokens in Flask, ensure file paths are resolved to their canonical absolute paths before any filesystem operation and enforce strict ownership checks that tie resolved paths to the authenticated principal represented by the token. Do not trust user-supplied path components; always sanitize and validate them independently of authentication state.
import os
from flask import Flask, request, jsonify
from werkzeug.utils import secure_filename
app = Flask(__name__)
# Example: resolve and validate file path based on authenticated user ID from Bearer token
@app.route('/uploads/', methods=['POST'])
def upload_file(username):
auth = request.headers.get('Authorization', '')
if not auth.startswith('Bearer '):
return jsonify({'error': 'missing_bearer_token'}), 401
token_user = extract_user_from_token(auth[7:]) # implement your token validation
if token_user != username:
return jsonify({'error': 'unauthorized'}), 403
file = request.files.get('file')
if not file:
return jsonify({'error': 'no file'}), 400
filename = secure_filename(file.filename)
base_dir = os.path.abspath('/safe/uploads')
user_dir = os.path.join(base_dir, username)
os.makedirs(user_dir, exist_ok=True)
target_path = os.path.join(user_dir, filename)
# canonicalize to prevent symlink escapes
canonical_dir = os.path.realpath(user_dir)
canonical_target = os.path.realpath(target_path)
if not canonical_target.startswith(canonical_dir + os.sep):
return jsonify({'error': 'invalid path'}), 400
file.save(canonical_target)
return jsonify({'path': canonical_target}), 201
def extract_user_from_token(token: str) -> str:
# placeholder: implement proper JWT or token introspection
return 'alice'
Key practices reflected in the example:
- Validate the Bearer token and map it to an authenticated identity before using it in path construction.
- Use
secure_filenameandos.path.realpathto canonicalize directories and final targets, preventing symlink resolution outside allowed directories. - Confirm that the resolved target remains within the intended directory by prefix comparison after canonicalization.
- Do not rely on the token alone to enforce file boundaries; enforce them at the filesystem path level.
Additionally, avoid creating temporary files with predictable names in shared directories, and prefer secure temporary file creation APIs when intermediate files are required. These steps reduce the risk that an authenticated request with a valid Bearer token can be coerced into operating on unintended files via symlink manipulation.