File Upload, SSRF & Deserialization (FIND/EXPLOIT — server input handling)
Overview
Three high-impact classes that often reach RCE or full cloud compromise and were previously
homeless across the references: untrusted files, untrusted URLs, and untrusted
serialized objects. All three are "the server processes attacker-supplied data."
Core principle: Anywhere the server fetches, stores+serves, or reconstructs attacker
data, ask what else it can be pointed at or made into.
Applies when / Skip when
- Applies when: the app accepts file uploads, fetches user-supplied URLs, or
deserializes input — test each of the three independently.
- Skip when: a given feature is absent → that part is N/A (e.g. no uploads → skip the upload
section but still test SSRF/deserialization if present).
- If N/A: report which of the three are absent and test only what exists.
⚠️ Authorization
Your own/authorized non-prod. SSRF can reach real internal infra and cloud creds — keep targets
to your environment; use benign canaries, don't pivot out of scope.
File upload
| Check |
Test |
| Type/extension bypass |
shell.php.jpg, double ext, null byte, case, .phtml/.svg/.htaccess |
| Content-type spoof |
Real image bytes + script; mismatched Content-Type header |
| Polyglot |
File valid as image and script (e.g. GIF/PHP) |
| Path traversal |
Filename ../../var/www/shell.php to control where it lands |
| Executable location |
Does it land in a web-served, executable dir? |
| Parser attacks |
Malicious SVG (XXE/XSS), Office/ZIP (zip-slip, XXE), image lib CVEs |
| Limits |
Size/rate limits; decompression bombs |
The kill condition is upload → reachable executable path → execution. If files are stored
outside webroot with random names and non-executable, most upload bugs lose their teeth.
SSRF
- Sinks: URL preview/unfurl, webhooks, import-from-URL, PDF/screenshot/image fetch, SSO
metadata, file:// handlers, server-side HTTP clients.
- Targets to prove (benign): your collaborator/OOB host, then
127.0.0.1/internal, then cloud
metadata http://169.254.169.254/latest/meta-data/ (AWS), metadata.google.internal (GCP).
- Bypasses to test: alternate IP encodings,
[::1], DNS rebinding, redirects, @-tricks,
allowlist parsing flaws.
- SSRF→cloud-metadata→IAM creds is a top chain to demonstrate (see
vulnerability-chaining).
Insecure deserialization
- Sinks:
pickle.loads, yaml.load, Java readObject, PHP unserialize, .NET
BinaryFormatter, Node node-serialize on untrusted input.
- Detect: serialized blobs in cookies/params/bodies; tampering changes server behavior.
- Confirm with a benign gadget (OOB ping) — don't run destructive gadget chains.
See references/upload-ssrf-recipes.md for payloads and safe confirmation.
Output
Per finding: sink, payload, evidence (where the file executed / OOB hit / object reconstructed),
and reachable impact (RCE, internal access, cloud creds). Usually High–Critical.
Hand-off
Frequently the foothold/pivot in vulnerability-chaining; reproduce via active-pentest; fix via
security-hardening (store outside webroot + validate content + random names; URL allowlist +
block internal ranges + IMDSv2; safe deserialization formats).
Common mistakes
- Checking only the file extension client-side — validate content server-side.
- Declaring "no SSRF" without testing redirects, DNS rebinding, and IP-encoding bypasses.
- Testing SSRF against real internal infra/prod — stay in your environment.
- Treating deserialization as theoretical — it's a common direct path to RCE.
1---2name: file-upload-and-ssrf3description: Use when testing file-upload handling, server-side request forgery (SSRF), and insecure deserialization — upload bypasses (type/extension/content, polyglots, path traversal), SSRF to cloud metadata and internal services, and unsafe deserialization sinks. On apps you own or are authorized to test.4---56# File Upload, SSRF & Deserialization (FIND/EXPLOIT — server input handling)78## Overview9Three high-impact classes that often reach RCE or full cloud compromise and were previously10homeless across the references: untrusted **files**, untrusted **URLs**, and untrusted11**serialized objects**. All three are "the server processes attacker-supplied data."1213**Core principle:** Anywhere the server *fetches*, *stores+serves*, or *reconstructs* attacker14data, ask what else it can be pointed at or made into.1516## Applies when / Skip when17- **Applies when:** the app accepts **file uploads**, **fetches user-supplied URLs**, or18 **deserializes** input — test each of the three independently.19- **Skip when:** a given feature is absent → that part is N/A (e.g. no uploads → skip the upload20 section but still test SSRF/deserialization if present).21- **If N/A:** report which of the three are absent and test only what exists.2223## ⚠️ Authorization24Your own/authorized non-prod. SSRF can reach real internal infra and cloud creds — keep targets25to your environment; use benign canaries, don't pivot out of scope.2627## File upload28| Check | Test |29|-------|------|30| Type/extension bypass | `shell.php.jpg`, double ext, null byte, case, `.phtml`/`.svg`/`.htaccess` |31| Content-type spoof | Real image bytes + script; mismatched `Content-Type` header |32| Polyglot | File valid as image **and** script (e.g. GIF/PHP) |33| Path traversal | Filename `../../var/www/shell.php` to control where it lands |34| Executable location | Does it land in a web-served, executable dir? |35| Parser attacks | Malicious SVG (XXE/XSS), Office/ZIP (zip-slip, XXE), image lib CVEs |36| Limits | Size/rate limits; decompression bombs |3738The kill condition is **upload → reachable executable path → execution**. If files are stored39outside webroot with random names and non-executable, most upload bugs lose their teeth.4041## SSRF42- **Sinks:** URL preview/unfurl, webhooks, import-from-URL, PDF/screenshot/image fetch, SSO43 metadata, file:// handlers, server-side HTTP clients.44- **Targets to prove (benign):** your collaborator/OOB host, then `127.0.0.1`/internal, then cloud45 metadata `http://169.254.169.254/latest/meta-data/` (AWS), `metadata.google.internal` (GCP).46- **Bypasses to test:** alternate IP encodings, `[::1]`, DNS rebinding, redirects, `@`-tricks,47 allowlist parsing flaws.48- SSRF→cloud-metadata→IAM creds is a top **chain** to demonstrate (see `vulnerability-chaining`).4950## Insecure deserialization51- **Sinks:** `pickle.loads`, `yaml.load`, Java `readObject`, PHP `unserialize`, .NET52 `BinaryFormatter`, Node `node-serialize` on untrusted input.53- Detect: serialized blobs in cookies/params/bodies; tampering changes server behavior.54- Confirm with a benign gadget (OOB ping) — don't run destructive gadget chains.5556See `references/upload-ssrf-recipes.md` for payloads and safe confirmation.5758## Output59Per finding: sink, payload, evidence (where the file executed / OOB hit / object reconstructed),60and reachable impact (RCE, internal access, cloud creds). Usually High–Critical.6162## Hand-off63Frequently the foothold/pivot in `vulnerability-chaining`; reproduce via `active-pentest`; fix via64`security-hardening` (store outside webroot + validate content + random names; URL allowlist +65block internal ranges + IMDSv2; safe deserialization formats).6667## Common mistakes68- Checking only the file extension client-side — validate content server-side.69- Declaring "no SSRF" without testing redirects, DNS rebinding, and IP-encoding bypasses.70- Testing SSRF against real internal infra/prod — stay in your environment.71- Treating deserialization as theoretical — it's a common direct path to RCE.