File Upload Handling

File uploads are a deceptively dangerous feature: they take attacker-controlled bytes and a filename and ask your server to store and later serve them. Done carelessly, they enable malware distribution, path traversal, stored XSS, and denial of service.

The guiding principle is simple — trust nothing the client tells you. Not the filename, not the MIME type, not the extension. Validate the actual content on the server, and store uploads where they can't be executed.

TL;DR

Quick Example

Validate by sniffing the real bytes (magic number), not the client-supplied extension or MIME type:

Core Concepts

Validation

Also enforce size limits and a maximum file count to prevent denial of service.

Storage options

Security

Generate your own filenames (never reuse the client's), block path traversal (../), store outside any executable path, scan for malware, and enforce access control on private files. See Application Security.

Common Patterns

Direct-to-storage with signed URLs

At scale, don't proxy file bytes through your API — let the client upload straight to storage:

Large files

Use multipart or resumable uploads (chunk, upload in parallel, reassemble), and push thumbnailing/transcoding into background jobs.

Common Mistakes

Trusting the extension or MIME type

Serving uploads from your app's origin

FAQ

How do I validate file type securely?

Inspect the file's actual content (magic numbers) on the server rather than trusting the extension or Content-Type, both of which the client controls. For images, re-encoding to a known format is the strongest defense because it discards embedded payloads.

Should files go to my server or directly to storage?

For anything beyond small files, use signed URLs so clients upload directly to object storage. It removes your API as a bandwidth bottleneck and single point of failure; your backend only issues the URL and records metadata afterward.

Why not serve uploads from my main domain?

A malicious HTML or SVG file served from your origin can execute as stored XSS against your users. Serve user content from a separate origin/CDN, force downloads with Content-Disposition, and apply a strict CSP.

Do I need virus scanning?

For any user-to-user file sharing, yes — scan uploads (e.g. ClamAV or a cloud scanning service) before making them available, ideally in a background job after the upload completes.

Related Topics

References