Zip Slip in Fastapi with Basic Auth
Zip Slip in Fastapi with Basic Auth — 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 unsanitized user input. In Fastapi, combining this vulnerability with Basic Authentication can expose subtle risks around file extraction and account enumeration, even when authentication is required.
When Basic Auth is used, credentials are sent in the Authorization header as a base64-encoded string. While this does not directly cause Zip Slip, it can influence how attacks are probed and observed. For example, an authenticated endpoint that extracts files from a user-supplied archive may trust the request identity but still fail to validate path segments. If the endpoint does not restrict traversal sequences like ../, an authenticated user can extract files outside the intended directory. In this scenario, authentication confirms identity but does not prevent malicious path manipulation, creating a scenario where access control is bypassed at the filesystem level.
Furthermore, error handling differences based on authentication state can leak information. An endpoint that returns detailed errors for authenticated users but generic responses for unauthenticated ones may expose whether a path traversal succeeded. This can aid an attacker in refining probes. Even though middleBrick tests unauthenticated attack surfaces, understanding how authentication layers interact with file handling logic is important for secure design. The presence of Basic Auth should not reduce scrutiny on input validation within archive extraction or file upload logic.
In API security scanning, this interaction is relevant to checks such as Input Validation and Property Authorization. A specification that defines a file-extract endpoint with security schemes using Basic Auth must still enforce strict path normalization and disallow traversal patterns. Runtime tests that upload or extract archives should validate that resolved paths remain within an allowed base directory. Without such controls, the combination of authenticated access and unchecked user input can lead to unauthorized file access or information disclosure.
Basic Auth-Specific Remediation in Fastapi — concrete code fixes
To remediate Zip Slip in Fastapi when using Basic Auth, ensure that user-controlled path components are strictly validated and that file operations are confined to a designated directory. Below are concrete code examples that demonstrate secure handling.
First, implement a secure path resolution utility that normalizes and confines paths:
import os
from pathlib import Path
def safe_path_join(base_dir: str, user_path: str) -> Path:
# Normalize and resolve the user input against the base directory
base = Path(base_dir).resolve()
target = (base / user_path).resolve()
# Ensure the resolved path remains inside the base directory
try:
target.relative_to(base)
except ValueError:
raise ValueError('Invalid path: traversal outside base directory')
return target
Next, use this utility in an endpoint that handles archive extraction with HTTP Basic Authentication:
from fastapi import Fastapi, Depends, HTTPException, Security
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import zipfile
app = Fastapi()
security = HTTPBasic()
def verify_credentials(credentials: HTTPBasicCredentials = Security(security)):
# Replace with secure credential verification
if credentials.username != 'admin' or credentials.password != 'secret':
raise HTTPException(status_code=401, detail='Invalid credentials')
return credentials
@app.post('/extract')
def extract_archive(
file_path: str,
credentials: HTTPBasicCredentials = Security(security)
):
verify_credentials(credentials)
base_directory = '/safe/extraction/directory'
try:
safe_path = safe_path_join(base_directory, file_path)
with zipfile.ZipFile(safe_path, 'r') as zf:
zf.extractall(path=safe_path.parent)
return {'status': 'extracted'}
except (ValueError, zipfile.BadZipFile, FileNotFoundError) as e:
raise HTTPException(status_code=400, detail=str(e))
This approach ensures that user input is confined, and authentication is enforced before any file system interaction. For production use, consider additional measures such as limiting archive contents, avoiding absolute paths, and using non-privileged filesystem permissions.