Learning on Web Dev Open is free for all.

Backend Engineering > Work that outlives the requestFiles, and why they should not touch your server
Phase 05Work that outlives the request272 of 434

Files, and why they should not touch your server

Presigned URLs, size limits before the bytes arrive, content-type you do not trust, and processing that happens afterwards.

Concept14 minAI implements

Routing a hundred megabyte upload through your application server means buffering or streaming it through a process that is also serving requests, on a platform that probably has a body size limit and definitely has a timeout. Issue a presigned URL instead: your server authorises the upload and returns a short-lived URL, the browser sends the bytes directly to object storage, and then tells your server the key. Your server handles two small JSON requests and no file at all.

Constrain the presigned URL when you issue it, because that is your only chance. A short expiry, a maximum size the storage service enforces, a key prefix derived from the authenticated user so nobody can overwrite anyone else's object, and a bound content type. Anything you do not constrain there is unconstrained.

Do not trust the declared type or the extension. A file called invoice.pdf can be anything, including something a downstream image processor will misinterpret. Sniff the actual bytes after upload, re-encode images rather than serving what was sent, and serve user content from a separate origin with Content-Disposition set, so a crafted upload cannot execute as script against your domain.

You should now be able to

  • Design an upload that goes straight to object storage
  • Enforce size and type limits safely
  • Explain why the client-declared content type is not evidence
Ask the community

Loading…