Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,17 @@ async def analyze_process(
SSE endpoint streaming real analysis progress from analyze_logs().
Fixes hardcoded progress messages by wiring progress_callback to the stream.
"""
# ── FIX 1: PATH TRAVERSAL PROTECTION ────────────────────────────────────
# Resolve the real absolute path and ensure it stays inside UPLOAD_DIR.
# Prevents attacks like file_path=../../etc/passwd
safe_path = os.path.realpath(file_path)
upload_dir_real = os.path.realpath(UPLOAD_DIR)
if not safe_path.startswith(upload_dir_real + os.sep):
raise HTTPException(
status_code=400,
detail="Invalid file path. Access outside upload directory is not permitted."
)
Comment on lines +301 to +307

queue: asyncio.Queue = asyncio.Queue()

def progress_callback(percent: int, message: str):
Expand All @@ -305,7 +316,7 @@ async def event_generator():
analysis_task = loop.run_in_executor(
None,
lambda: analyze_logs(
file_path,
safe_path,
threshold_seconds=threshold,
progress_callback=progress_callback,
),
Expand Down Expand Up @@ -336,9 +347,9 @@ async def event_generator():


@app.post("/verify-chain")
#@limiter.limit("30/minute")
@limiter.limit("30/minute") # FIX 2: re-enabled rate limiting (was commented out)
async def verify_chain_manifest(
request: Request,
request: Request, # required by slowapi for IP-based rate limiting
manifest: list = None,
current_user: str = Depends(get_current_user),
):
Expand Down Expand Up @@ -449,4 +460,4 @@ async def get_chain_status(

if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
uvicorn.run(app, host="127.0.0.1", port=8000)
Loading