# Executable file upload to web-served path

Uploads stored where the server executes them; validator and executor disagree on extension or archive member

_Area: Web injection and code execution. Seen in 7 disclosed reports; 3 confirmed bounties, median $3,100, range $1,337-$5,600; latest 2026-09-30. Updated 2026-10-23._

## How it works
An upload handler decides a file is acceptable using one signal (extension, MIME type, inner archive name, or a filename parameter), then stores it where a web server or interpreter decides what to do using a different signal. When the two disagree, attacker-controlled content runs as code. The broken assumption: the validator and the executor parse the same thing the same way. Sometimes there is no validation at all, and the only thing between an upload and execution is the storage location [E1](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-parks-recreation-platform-webshell-attack.md)[E2](https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md).

## Where it shows up
- Upload sinks writing into web-accessible directories served by IIS, Apache, or PHP [E1](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-parks-recreation-platform-webshell-attack.md)[E2](https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md)
- Export/report handlers taking both a filename and a content parameter [E4](https://bugbountylibrary.com/r/h1%3A1072832.md)
- Archive uploads where the validator reads the first suffix and the web server maps the trailing one [E6](https://bugbountylibrary.com/r/blog%3Amachevalia-blog-blog-remote-code-execution-in-tgz-file-upload.md)
- Blacklists comparing the raw extension string, missing trailing space or dot [E7](https://bugbountylibrary.com/r/h1%3A506646.md)
- Validators built on content sniffing (e.g. `getimagesize()`) that accept non-image magic bytes [E3](https://bugbountylibrary.com/r/blog%3Aahussam-me-leaking-wordpress-csrf-tokens.md)
- Handlers with no authentication, which widens reach but is not the type mismatch itself [E2](https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md)

## How to review
Trace every upload/export sink to where the file is served or interpreted. The invariant: the type decision at validation must be the same decision the executor makes, and the storage path must not be executable. Check:
- Allow-list extensions, storage outside the docroot, `Content-Disposition: attachment` with a safe type.
- Archive inner names validated against the executor's parsing, not just the outer name [E6](https://bugbountylibrary.com/r/blog%3Amachevalia-blog-blog-remote-code-execution-in-tgz-file-upload.md).
- Whether an export filename parameter influences the stored path or extension [E4](https://bugbountylibrary.com/r/h1%3A1072832.md).
- Whether the filter normalizes the extension the way the OS does (trailing space/dot) [E7](https://bugbountylibrary.com/r/h1%3A506646.md).
- Whether content sniffing accepts non-image formats the browser will still execute [E3](https://bugbountylibrary.com/r/blog%3Aahussam-me-leaking-wordpress-csrf-tokens.md).
- Authentication present on every upload handler, as a contributing control [E2](https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md).

## Variants seen
- Direct server-side script upload to a web-served dir, no validation [E1](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-parks-recreation-platform-webshell-attack.md)[E2](https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md)
- Export filename/content parameter writing a webshell [E4](https://bugbountylibrary.com/r/h1%3A1072832.md)
- Double-extension `.pdf.php` passing inner-name validation in an archive [E6](https://bugbountylibrary.com/r/blog%3Amachevalia-blog-blog-remote-code-execution-in-tgz-file-upload.md)
- Trailing-space extension bypass of a blacklist on IIS [E7](https://bugbountylibrary.com/r/h1%3A506646.md)
- Content-sniffing validator accepting SWF magic bytes, served same-origin [E3](https://bugbountylibrary.com/r/blog%3Aahussam-me-leaking-wordpress-csrf-tokens.md)

## Impact and severity
Led to RCE as the web app pool and cross-server compromise [E1](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-parks-recreation-platform-webshell-attack.md)[E2](https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md)[E6](https://bugbountylibrary.com/r/blog%3Amachevalia-blog-blog-remote-code-execution-in-tgz-file-upload.md). Severity is highest when the handler is unauthenticated or reachable by a low-privilege account and stored files sit in an executable directory [E1](https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-parks-recreation-platform-webshell-attack.md)[E2](https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-parks-recreation-platform-webshell-attack.md
- E2: https://bugbountylibrary.com/r/blog%3Akamilonurozkaleli-com-posts-rce-on-starbucks-singapore-and-more.md
- E3: https://bugbountylibrary.com/r/blog%3Aahussam-me-leaking-wordpress-csrf-tokens.md
- E4: https://bugbountylibrary.com/r/h1%3A1072832.md
- E5: https://bugbountylibrary.com/r/h1%3A452559.md
- E6: https://bugbountylibrary.com/r/blog%3Amachevalia-blog-blog-remote-code-execution-in-tgz-file-upload.md
- E7: https://bugbountylibrary.com/r/h1%3A506646.md
