Think Build Implement Repeat
London, UK +44 7367 067226
WhatsApp FOLLOW f in X
Python & Django

Uploads, Storage and Controlled Access

Last updated:

Never serve private files directly

A file at a guessable URL is not access controlled. Private documents must be served through a view that authenticates, authorises and then streams the file.

The most common document security failure in business applications is a PDF at a predictable URL that nobody checks permissions for.

Upload handling

  1. Store outside the code directory, or in object storage
  2. Validate content, not the extension or the reported type
  3. Generate your own filename, never using the uploaded one
  4. Limit size and type, enforced server-side
  5. Never build a path from anything a user supplied

Object storage once you scale

OptionSuits
Local disk outside the code directorySingle server, modest volume
Object storageMultiple servers, redundancy, any real volume
DatabaseRarely — small files only, complicates backups

Object storage with signed URLs handles both the access control and the serving efficiently, and it removes files from your backup burden.

Generated documents

  • Generate in the background, not during a request
  • Store what was produced rather than regenerating
  • Record which template version produced it
  • Never overwrite a document that has been sent
  • Retain according to your records policy

An invoice regenerated next year may differ, because the template or a product name changed. The document you sent is the record.

Include files in backups

Uploaded files are frequently outside the database backup and therefore outside the backup entirely. A restore that recovers records and not documents is a partial restore.

Check specifically, and test restoring both together.

Frequently asked questions

How do we serve private files?

A view that checks permissions then streams the file, or object storage with short-lived signed URLs.

Should uploads be scanned?

Where files will be shared with other users, yes. For files only the uploader retrieves, the risk is lower.

What about large uploads?

Direct to object storage with signed URLs, bypassing the application. That avoids memory and timeout problems.

Are uploaded files in our backups?

Check specifically. They are commonly missed and it is discovered during a restore.

Keep reading

Documents at guessable URLs?

That is not access control. Serving through a permission-checking view is a contained fix.

Book a free 30-minute call Get a project estimate WhatsApp us

Related services

What we build for problems like this one

Custom Software DevelopmentWeb DevelopmentMachine Learning