File upload: from profile picture to webshell
Accepting files from users is risky if the file can be executed or served. The worst case: uploading shell.php into a folder served by the web server.
The common bypasses
Extension-only check: bypassed with shell.php.jpg, double extensions, .phtml, or uppercase. Content-Type-only check: it is set by the client. Magic-bytes check: put a valid GIF header before PHP code (GIF89a;<?php...). Path traversal in the name to escape the upload folder.
Content-Type: image/jpeg
filename="a.php"
GIF89a;<?php system($_GET['c']); ?>Defence
Strict extension whitelist, rename files with generated names, store outside the webroot or in storage that does not execute code, serve with Content-Disposition: attachment. Disable execution in the upload folder (nginx: no PHP handler there). Validate the real content, limit size and type.