Safeguard
Security Guides•

What should a code review check in file upload handling?

Check the extension allow list, ignore the client content type, rename on the server, store outside the webroot, cap sizes and require login.

Safeguard Security Team
4 min read

A reviewer should check eight things in upload code: an extension allow list, no trust in the client supplied content type, a server generated filename, storage outside the web root, size limits, content validation, an authenticated and authorized uploader, and scanning where it fits. Missing any one is a reason to comment.

The checklist, from OWASP

The OWASP File Upload Cheat Sheet groups its advice in a way that maps cleanly to review comments.

ControlWhat to look for in the diff
Extension allow listA short list of permitted types, validated after decoding the filename. Block lists alone are weak
Content typeThe Content-Type header is not trusted. It comes from the client and is easy to spoof
FilenameThe server generates the stored name, such as a random UUID, so user input never controls the path
Storage locationOutside the web root, ideally a separate host, with per directory config overrides disabled
Size limitsA cap on upload size, and on decompressed size for archives
Content validationImages re-encoded to an allowed format with metadata stripped
AuthenticationA known user who is authorized to upload and to access the files
ScanningAntivirus or sandbox checks, and content disarm for document types where applicable

Reading the code

  1. Start with the route. Is it behind authentication? Many upload bugs are simply public endpoints.
  2. Find where the filename is used. If any part of the stored path comes from the request, flag it.
  3. Find the type check. If it reads the header the client sent, ask for a check on the actual file.
  4. Find the storage call. Check the target directory and whether files can be served and executed from it.
  5. Find the limits. Look for a maximum size at the web server and in application code.
  6. Check what happens after upload. Files that are previewed, converted or unpacked get parsed by libraries, which is its own attack surface.
# risky: the client controls the name and location
path = os.path.join(UPLOAD_DIR, request.files["f"].filename)

# safer: the server controls both
path = os.path.join(UPLOAD_DIR, str(uuid.uuid4()) + ".png")

Archives and documents

The cheat sheet advises avoiding ZIP files where possible and checking decompressed sizes, because a small archive can expand into a very large one. For document types such as PDF and DOCX, it mentions content disarm and reconstruct as an option. These are heavier controls, so decide by risk. A profile picture endpoint and a document sharing feature deserve different levels of care.

Tests worth asking for

Ask for a test that uploads a file with a mismatched extension and content, one with a traversal sequence in the name, and one over the size limit. If the tests do not exist, the controls often do not either.

Try it yourself

Run the web scan in the demo and look at how a dynamic scan reports issues on upload forms and responses.

Click through it at your own pace, or open it full screen.

Where Safeguard fits

Safeguard scans your dependencies, including image and document libraries your upload code relies on. Start with the free scan at gold.safeguard.sh/scan.

Quick check

Can I trust the Content-Type header on an upload?

No. OWASP notes it comes from the client and is easy to spoof, so verify the actual file.

Why rename uploaded files?

So user input never controls the stored path or name.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.