# Unsafe deserialization of untrusted input

Attacker bytes reaching unserialize, YAML.load, BinaryFormatter, phar://, AMF or session sinks

_Area: Web injection and code execution. Seen in 15 disclosed reports; 9 confirmed bounties, median $1,250, range $300-$20,000; latest 2026-10-20. Updated 2026-10-23._

## How it works
A deserializer rebuilds objects from bytes, so the input chooses which classes get instantiated and which lifecycle hooks (`__wakeup`, `__destruct`, `readObject`) run. If any loaded class has a hook that reaches a dangerous operation, the bytes become executable structure, not inert data. The broken assumption is that serialized input is trusted data. A distinct sub-class is memory corruption inside the deserializer runtime itself: PHP's garbage collector had a use-after-free where a freed zval could be reused as an attacker-controlled zval, giving arbitrary read and function-pointer hijack even when no gadget chain exists [E1](https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20220709205125-https-www-evonide-com-how-we-broke-php-hacked-pornhub-and-earned-20000-dollar.md).

## Where it shows up
- `unserialize(` on cookies, POST fields, or database content re-parsed later [E1](https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20220709205125-https-www-evonide-com-how-we-broke-php-hacked-pornhub-and-earned-20000-dollar.md)[E4](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md)
- `YAML.load` / `load_file` on config from cloned repos or uploads [E5](https://bugbountylibrary.com/r/h1%3A2438265.md)
- `BinaryFormatter.Deserialize` with no type restriction, e.g. inside an IIS HTTP module [E3](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md)
- `phar://` reaching filesystem functions like `is_dir` [E2](https://bugbountylibrary.com/r/blog%3Athinkloveshare-com-hacking-preauth-remote-code-execution-web-page-test.md)
- Java AMF endpoints deserializing without a class allowlist [E6](https://bugbountylibrary.com/r/h1%3A728614.md)
- Unsafe SnakeYAML default `Constructor` exposed by a library API [E7](https://bugbountylibrary.com/r/h1%3A1807214.md)
- Base64-decode immediately before a deserialization call [E3](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md)[E4](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md)

## How to review
Trace every byte path from request to a deserialization sink. The invariant: untrusted input must never reach a deserializer that can instantiate arbitrary types. Grep the sinks above, then for each call site ask whether input is attacker-reachable and whether a type allowlist is enforced. `safe_load` with an allowlist, or `allowed_classes` restricted to a fixed set, is not a finding. Note `YAML.load`/`load_file` deserialize objects, while `safe_load` only parses data. Check for base64-decode-before-unserialize, which hides payloads from naive greps [E3](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md)[E4](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md). For phar://, confirm every filesystem sink prefixes paths consistently; phar:// accepts a trailing `/subitem`, so a path ending in a dot can still resolve [E2](https://bugbountylibrary.com/r/blog%3Athinkloveshare-com-hacking-preauth-remote-code-execution-web-page-test.md). For IIS modules, grep `web.config` `httpModules` for upload/deserialize handlers, since modules run on every request regardless of route [E3](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md). For second-order flows, check whether an unauthenticated write is later re-parsed by a privileged workflow [E4](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md).

## Variants seen
- PHP unserialize plus GC use-after-free for RCE [E1](https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20220709205125-https-www-evonide-com-how-we-broke-php-hacked-pornhub-and-earned-20000-dollar.md)
- Second-order object injection: stored data re-parsed by a migration engine [E4](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md)
- phar:// deserialization through one forgotten path prefix [E2](https://bugbountylibrary.com/r/blog%3Athinkloveshare-com-hacking-preauth-remote-code-execution-web-page-test.md)
- BinaryFormatter sink in an IIS HTTP module [E3](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md)
- Java AMF deserialization without allowlist [E6](https://bugbountylibrary.com/r/h1%3A728614.md)
- YAML.load on repo config file [E5](https://bugbountylibrary.com/r/h1%3A2438265.md)
- Unsafe SnakeYAML Constructor exposed by a library API [E7](https://bugbountylibrary.com/r/h1%3A1807214.md)

## Why fixes fail
Prefix-based phar blocks miss one sink [E2](https://bugbountylibrary.com/r/blog%3Athinkloveshare-com-hacking-preauth-remote-code-execution-web-page-test.md). Second-order sinks survive because the unauthenticated write looks harmless until a privileged workflow re-parses it [E4](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md). Allowlist checks covering only the first deserialization call miss re-parsed stored data [E4](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md).

## Impact and severity
Full RCE and web shells [E1](https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20220709205125-https-www-evonide-com-how-we-broke-php-hacked-pornhub-and-earned-20000-dollar.md)[E2](https://bugbountylibrary.com/r/blog%3Athinkloveshare-com-hacking-preauth-remote-code-execution-web-page-test.md)[E3](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md). Critical when pre-auth and reachable from any route [E3](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md); worse when the deserialized object can reach filesystem or process operations [E2](https://bugbountylibrary.com/r/blog%3Athinkloveshare-com-hacking-preauth-remote-code-execution-web-page-test.md)[E5](https://bugbountylibrary.com/r/h1%3A2438265.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20220709205125-https-www-evonide-com-how-we-broke-php-hacked-pornhub-and-earned-20000-dollar.md
- E2: https://bugbountylibrary.com/r/blog%3Athinkloveshare-com-hacking-preauth-remote-code-execution-web-page-test.md
- E3: https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044.md
- E4: https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-high-severity-unauthenticated-php-object-injection-in-duplicator.md
- E5: https://bugbountylibrary.com/r/h1%3A2438265.md
- E6: https://bugbountylibrary.com/r/h1%3A728614.md
- E7: https://bugbountylibrary.com/r/h1%3A1807214.md
- E8: https://bugbountylibrary.com/r/h1%3A1842674.md
