liveBook · Manning

File upload

As explained in Grokking Web Application Security

A file upload is the transfer of a file from a client to a web server or other service.

A file upload lets a client send data that an application may write to disk. That makes uploads useful for sharing media, importing CSV or Excel data, and file-sharing features—but also a direct path for attackers to plant software or overwrite files. Treat every upload as untrusted input, regardless of what its filename or browser-reported type claims. section 11.9 section 11.0

Validate uploads on the server before accepting them. Check a maximum size, constrain filename length and characters, reject path characters such as ../, require an expected extension, and inspect file-type headers. Filename extensions can be misleading, and browser-side checks improve feedback but provide no server security because attackers can send requests without using the browser. section 4.7 section 11.10

Size and storage controls address distinct upload risks:

  • Reject oversized files to reduce denial-of-service risk. Apply limits while unpacking archives as well, since a zip bomb can expand until it consumes available disk space. section 11.10
  • Reject path-like filenames and tightly limit allowed characters and length. Relative paths can let an attacker overwrite sensitive server files. section 11.10
  • Check both the expected extension and file headers, but do not treat a header check as a complete malicious-content scan. A crafted file can be valid in more than one format. section 4.7 section 11.10
  • Keep uploaded files non-executable. Restrict the web server process to only required directories and prevent it from executing files in any uploadable directory. section 11.12

PNG type check

A server can use Magic, a Python wrapper for Linux libmagic, to inspect an uploaded file’s MIME type and require image/png. This is a useful enforcement step, not proof that the file is harmless. section 4.7 section 11.10

import magic

file_type = magic.from_file("upload.png", mime=True)

assert file_type == "image/png"

This minimal server-side check illustrates verifying a claimed PNG through its detected MIME type rather than trusting its name alone. section 11.10

If possible, keep uploads at arm’s length by storing them in a third-party content-management or web-storage service. When writing locally, save with read-write permissions only; never grant execute permission to an uploaded file, or a script upload may become a web shell that runs commands through HTTP. section 4.7 section 11.12

How Grokking Web Application Security covers it

How deep it goes
Explains filename, size, type, archive, and permission checks, while noting header validation only scratches the surface.
Examples
Uses image uploads, CSV and Excel imports, a PNG MIME check, zip bombs, and a PHP web shell.
What you can do after
Operate/configure file uploads with server-side validation, bounded archive handling, restricted filenames, and non-executable storage permissions.
How it connects
Connects file uploads to denial of service, path traversal, web shells, file permissions, and server-side validation.

Also explained in

Compare how 5 books explain file upload →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Web Application Security. The section links point to the parts of the book it draws on.