Will It Vibe logoWill It Vibe?
DJANGO-025High severity-15 points

File served from a request-controlled path

Part of Security, which counts for 30% of the overall score. When this check fires it deducts 15 points from that category, once per scan, no matter how many places it turns up.

What it detects

open() or FileResponse() is called with a path built directly from request.GET/POST/data, with no visible '..' check, safe_join(), or resolve()/is_relative_to() guard nearby. A request for a value like '../../etc/passwd' reads whatever file that traversed path resolves to.

Why it matters

open() or FileResponse() is called with a path built directly from request.GET/POST/data, with no '..' check, safe_join(), or resolve()/is_relative_to() guard nearby. A request supplying '../../etc/passwd' or an absolute path traverses out of the intended directory, letting an attacker read arbitrary files the Django process has access to, including settings modules, .env files, and other users' uploads.

How to fix it

Never pass a request-derived path straight to open()/FileResponse(). Resolve it against the intended base directory and verify containment before opening: joined = (base_dir / user_supplied_name).resolve(); if not joined.is_relative_to(base_dir.resolve()): raise Http404 or PermissionDenied. For files that map to a database record, prefer looking the record up with get_object_or_404() and serving its stored path rather than trusting a client-supplied filename at all.

The paid report includes a ready-to-paste prompt for your AI coding agent for every check it finds, pointed at the exact findings from your scan. See pricing

Does your repo trip this check?

Paste a GitHub URL or drop a project folder. Scans run in your browser and take seconds.

Scan your repo

Related Security checks