Backend Development › Backend Basics · also in Files & Media
File Uploads
Accepting, validating and storing files from users.
A file upload sends a file from the user’s device to your server, usually as multipart form data. The file comes from someone you don’t trust, so treat it as untrusted input.
On the frontend, a file input is the start of the upload:
<form method="post" action="/avatar" enctype="multipart/form-data">
<input type="file" name="avatar" accept="image/png,image/jpeg">
<button>Upload</button>
</form>
The accept attribute only filters the file picker. It doesn’t stop anyone from sending another file, so the server has to check on its own. On the backend:
- Limit the size before the whole file is read into memory.
- Check the actual content of the file, not just its extension.
photo.pngcan contain anything. - Don’t use the user’s filename as the storage path. Generate a name yourself, so a crafted filename can’t point outside your storage folder.
- Store the file outside the application code, in object storage such as S3 or a dedicated volume. See ephemeral filesystem for why.
The classic mistake is trusting the extension and the filename, then saving the upload to a path built from them. Validate, rename and store the file, and only then record it in your database.