Zip Slip in Fastapi with Cockroachdb
Zip Slip in Fastapi with Cockroachdb — how this specific combination creates or exposes the vulnerability
Zip Slip is a path traversal vulnerability that occurs when a filename from user input is used to build filesystem paths without proper validation. In a Fastapi application that interacts with Cockroachdb, the risk emerges not from Cockroachdb itself but from how file paths are handled before data is written or read from storage used by the database layer. For example, if an endpoint accepts a user-supplied archive file name or a directory path to store exported data, and then concatenates it directly with a base path (e.g., os.path.join(UPLOAD_DIR, user_filename)), an attacker can supply sequences like ../../../etc/passwd to escape the intended directory. Because Fastapi often receives file uploads or path parameters for export routines that feed into Cockroachdb operations (such as importing CSV dumps), the unchecked path traversal can lead to unauthorized file reads or writes on the host filesystem. This becomes a vector to reach sensitive configuration files, application source code, or database credentials that inform how the app connects to Cockroachdb. Note that Cockroachdb does not introduce the flaw; the issue is rooted in path handling logic. middleBrick detects such insecure path construction during its Input Validation and Property Authorization checks, highlighting traversal risks even when the endpoint is unauthenticated.
Cockroachdb-Specific Remediation in Fastapi — concrete code fixes
To mitigate Zip Slip in a Fastapi service that uses Cockroachdb, enforce strict path normalization and validation before any filesystem interaction. Always resolve and verify that the final path remains within the intended directory. Below are concrete examples demonstrating safe patterns.
Safe path resolution with pathlib
Use Python’s pathlib.Path and resolve() to canonicalize user input and prevent directory escapes. This approach works regardless of whether your app stores metadata or file-based artifacts related to Cockroachdb operations.
from pathlib import Path
from fastapi import FastAPI, UploadFile, HTTPException
import os
app = FastAPI()
BASE_DIR = Path("/safe/upload/dir").resolve()
@app.post("/upload-report/")
async def upload_report(file: UploadFile):
if not file.filename:
raise HTTPException(status_code=400, detail="Empty filename")
# Normalize and resolve the user filename
candidate = (BASE_DIR / file.filename).resolve()
# Ensure the resolved path is still under BASE_DIR
if os.path.commonpath([candidate, BASE_DIR]) != os.path.commonpath([BASE_DIR]):
raise HTTPException(status_code=400, detail="Invalid path traversal")
target_path = candidate # safe to write
with open(target_path, "wb") as f:
content = await file.read()
f.write(content)
# Here you might trigger a Cockroachdb import job using target_path
return {"status": "saved", "path": str(target_path)}
Validated filename with allowed patterns
Constrain filenames to a strict allowlist of characters and extensions. This reduces the risk of traversal sequences and special filesystem characters that could bypass weak checks.
import re
from fastapi import Fastapi, Form, HTTPException
from pathlib import Path
app = FastAPI()
BASE_DIR = Path("/exports").resolve()
SAFE_PATTERN = re.compile(r"^[a-zA-Z0-9._-]+\.csv$")
@app.post("/export-data/")
async def export_data(table_name: str = Form(...), filename: str = Form(...)):
if not SAFE_PATTERN.match(filename):
raise HTTPException(status_code=400, detail="Invalid filename format")
safe_path = (BASE_DIR / filename).resolve()
if os.path.commonpath([safe_path, BASE_DIR]) != os.path.commonpath([BASE_DIR]):
raise HTTPException(status_code=400, detail="Path escape detected")
# Proceed to generate CSV and interact with Cockroachdb as needed
return {"path": str(safe_path)}
Middleware and utility checks
Consider adding a lightweight validation utility used across endpoints to centralize path safety. This is helpful when multiple routes handle file uploads or dynamic paths tied to Cockroachdb operations.
from fastapi import Request, HTTPException
import os
from pathlib import Path
def validate_within_directory(directory: Path, target: Path) -> bool:
# Ensures target resides within directory
return os.path.commonpath([directory.resolve(), target.resolve()]) == os.path.commonpath([directory.resolve()])
@app.middleware("http")
async def validate_paths_middleware(request: Request, call_next):
# Example: block known risky path patterns in query or body for endpoints touching storage
response = await call_next(request)
return response
By combining canonical resolution, strict filename policies, and centralized checks, you reduce the likelihood of Zip Slip affecting your Fastapi service, even when workflows involve Cockroachdb interactions.