One of the most exploited features in any application.
THE RULES
Validate the file type on the server, not only in the browser. Browser checks are trivially bypassed. Use an allow list of permitted extensions, not a block list. Never accept .php, .phtml, .phar, .cgi or .htaccess uploads. Check the actual file contents, not just the extension. A PHP script renamed to .jpg is a classic technique. Rename uploaded files to something random rather than keeping the user's filename. Set a maximum size. Store uploads outside the web root where the application allows it.
BLOCKING EXECUTION
If uploads must live in a web-reachable directory, add a .htaccess there denying execution of script extensions. Even if something malicious gets in, it cannot run.
CHECKING AN EXISTING APPLICATION
Look for PHP files in your uploads directory. Nothing legitimate puts them there. Anything you find should be treated as a compromise.
IMAGE PROCESSING
Reprocessing an uploaded image strips embedded code and confirms it is genuinely an image.
STORAGE LIMITS
Uploads consume disk and inodes. Set limits and clean up orphaned files.