Back to Technical Mode

Malicious File Upload

File upload features are a favorite path to remote code execution — a file's extension and declared content-type are just labels the attacker chooses, not proof of what's actually inside.

The file extension (.jpg, .png) is attacker-controlled and proves nothing
The declared Content-Type header is also attacker-controlled and proves nothing
Magic-byte inspection reads the file's actual binary signature to verify its real type
Uploaded files should be stored outside the web root and served from a non-executable, isolated origin

Want this flow explained in detail as it plays?

POST/api/uploads/avatar

Headers

Host:app.flowground.dev
Content-Type:multipart/form-data; boundary=----BoundaryFlowGround

Body

Loading...

Quick-Insert Payloads

Defense in depth

  • Magic-byte (file signature) validation reads the first bytes of the actual file — a real JPEG must start with FF D8 FF
  • Extension is re-derived from the verified content type, never trusted from the client's filename
  • Uploaded files are stored outside the web root, in object storage with no execute permissions, and served from a separate, cookie-less origin

Vulnerable vs. Fixed

// DO NOT DO THIS
if (filename.endsWith(".jpg") || contentType === "image/jpeg") {
  saveToWebRoot(file); // never inspects actual file bytes
}