HIGH zip slipflaskbearer tokens

Zip Slip in Flask with Bearer Tokens

Zip Slip in Flask with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Zip Slip is a path traversal vulnerability that occurs when an application constructs file paths using user-supplied input without proper validation. In a Flask application that uses Bearer Tokens for authentication, the combination of file extraction logic and token handling can inadvertently expose sensitive endpoints or enable unauthorized access if path traversal is possible during archive extraction.

Consider a Flask route that accepts an uploaded ZIP file and extracts it to a destination directory. If the archive contains entries with crafted paths such as ../../../etc/passwd, and the server uses simple string concatenation to build the extraction path, files can be written outside the intended directory. When Bearer Tokens are used, an authenticated client includes the token in the Authorization header. If the server also uses the token value (or a portion of it) to derive a storage location or to name extracted artifacts without sanitization, an attacker can manipulate the archive contents to traverse directories and potentially overwrite or expose token-related files or configuration artifacts.

For example, an API endpoint that receives a ZIP and a Bearer token might extract the archive into a per-token directory like /data/uploads/{token}/. If the ZIP includes a file named ../../config/secrets.yml, and the server does not sanitize the member path, the file could escape the token directory and write into system configuration paths. This exposes secrets that may be referenced by the token-handling logic. Even if the token itself is not stored in the file system, an attacker can probe whether token-scoped directories are created and whether traversal can reach other user directories, enabling enumeration or privilege escalation across tenant boundaries (a BOLA/IDOR pattern).

The risk is compounded when the server returns information about extraction results or logs paths without redaction. An attacker can include paths designed to traverse into directories where Bearer Token artifacts (such as cached credentials or temporary keys) might exist, and then infer the internal layout via error messages or directory listing responses. Because middleBrick tests for Path Traversal and BOLA/IDOR in parallel, scans of such an endpoint would flag both the traversal risk and the potential for unauthorized access across user boundaries.

In summary, Zip Slip in Flask becomes critical in the presence of Bearer Tokens when token-derived paths or token-related data are used to determine where extracted content is written. Without strict input validation and path canonicalization, an attacker can leverage a malicious archive to escape intended storage boundaries and access or corrupt data associated with the token scope.

Bearer Tokens-Specific Remediation in Flask — concrete code fixes

To mitigate Zip Slip in Flask when using Bearer Tokens, ensure that file paths are validated and isolated per token scope. Below are concrete, secure code examples demonstrating proper handling.

Secure extraction with path sanitization

Use os.path.normpath and os.path.commonpath to ensure extracted members remain within the intended directory. Do not rely on the archive member path alone.

import os
import zipfile
from flask import Flask, request, abort

app = Flask(__name__)

def safe_mkdir(token_dir):
    os.makedirs(token_dir, exist_ok=True)

def extract_safe(zip_data, token):
    token_dir = os.path.abspath(f'/data/uploads/{token}')
    safe_mkdir(token_dir)
    with zipfile.ZipFile(zip_data) as zf:
        for member in zf.namelist():
            # Remove leading slash and dots to prevent directory traversal
            member = member.lstrip('/')
            member = '/'.join([p for p in member.split('/') if p and p != '..'])
            member_path = os.path.normpath(member)
            # Ensure final path stays within token_dir
            full_path = os.path.join(token_dir, member_path)
            if not os.path.commonpath([token_dir, full_path]) == token_dir:
                abort(400, 'Invalid path in archive')
            zf.extract(member, full_path)
    return True

@app.route('/upload', methods=['POST'])
def upload():
    auth = request.headers.get('Authorization', '')
    if not auth.startswith('Bearer '):
        abort(401, 'Missing Bearer token')
    token = auth[7:].strip()
    if not token:
        abort(400, 'Invalid token')
    file = request.files.get('archive')
    if not file:
        abort(400, 'Missing archive')
    # Pass file stream and token to secure extractor
    if extract_safe(file.stream, token):
        return {'status': 'ok'}, 200

Token isolation and input validation

Always treat the Bearer Token as an identifier, not as part of the filesystem path without sanitization. Use a deterministic mapping to storage directories and avoid including raw token characters in filenames.

import hashlib
import uuid

def token_storage_dir(token):
    # Derive a safe directory name from the token hash
    token_hash = hashlib.sha256(token.encode()).hexdigest()
    return os.path.abspath(f'/data/uploads/{token_hash}')

def store_upload(file_stream, token):
    base = token_storage_dir(token)
    safe_mkdir(base)
    filename = str(uuid.uuid4()) + '.bin'
    filepath = os.path.join(base, filename)
    file_stream.save(filepath)
    return filepath

Dependency and configuration hygiene

Ensure that any third‑party extraction libraries are pinned to versions without known Zip Slip vulnerabilities. Avoid recursive extraction and disable symlink creation during extraction.

# Example with zipfile (standard library) — safe defaults
with zipfile.ZipFile(archive_path) as zf:
    for info in zf.infolist():
        if hasattr(info, 'is_dir') and info.is_dir():
            continue
        # Do not extract if would escape target
        member_names = [info.filename]
        for name in member_names:
            if name.endswith('/'):
                continue
            # Validate as above

By combining strict path canonicalization, token hashing for storage directories, and rejecting archives with unsafe members, Flask applications can safely handle user uploads while preserving token isolation and avoiding Zip Slip.

Frequently Asked Questions

How does middleBrick detect Zip Slip risks in Flask APIs that use Bearer Tokens?
middleBrick runs parallel security checks including Path Traversal and BOLA/IDOR. By scanning the unauthenticated attack surface and analyzing OpenAPI specs alongside runtime behavior, it identifies unsafe archive extraction patterns and token-scoped directory exposure that can enable Zip Slip.
Can middleBrick test authenticated Bearer Token flows for Zip Slip scenarios?
middleBrick focuses on unauthenticated scanning. For Bearer Token workflows, supply an endpoint that accepts a token in the Authorization header; the scanner will test the exposed surface without using credentials, while checks like Authentication and BOLA/IDOR help surface related authorization risks.