Skip to main content

Handle uploads as untrusted input

Treat every uploaded file as untrusted input, the same as any text field.


An uploaded file can carry code. An SVG is an XML document that can contain <script> elements, event handler attributes, and external entity references, and browsers run all of it when the file is served as image/svg+xml and loaded directly.


Apply all of the following to every upload path, including ones that only staff use:

  • Validate size, extension, declared MIME type, and the actual file signature, and require them to agree. File type detection can be bypassed, so combine this step with the ones below.
  • Generate the stored filename yourself. Never use supplied filenames as identifiers. Store them as metadata instead.
  • Store uploads outside any directory that your application serves or executes from. Use hosted object storage.
  • Serve files with an explicit Content-Type and Content-Disposition, so that attackers can't chain a malicious file with a vulnerability in client code.
  • Re-encode images through a trusted processing pipeline rather than storing the original bytes. Re-encoding drops embedded payloads as a side effect of rewriting the pixels. Managed image services can do this for you.
  • Reject SVG, XML, and HTML uploads unless your product truly requires them. If it does, then sanitize them and serve them from a separate origin, so they can't reach your session cookies.

Was this page helpful?