File uploads with no type, size or ownership checks
What you'd see: Your upload handler takes file.name and file.type and saves the file.
What's actually happening
Both of those values come from the client and both can be set to anything. A file called photo.png can contain a PHP script; a file claiming image/jpeg can be a 4 GB zip. If the destination is publicly served and executable, that is a very short path to running code on your server.
Why an AI tool writes it this way
"Let users upload a profile picture" describes the happy path, and the happy path is what gets built. The accept="image/*" attribute on the input looks like validation, but it only filters the file picker dialog.
What it costs you
Ranges from storage bills and broken pages to remote code execution on hosts that run PHP from the upload directory. Even without execution, an unbounded upload endpoint is a free file host — and you pay the bandwidth.
Before & after
The upload box that accepts anything
Illustrative code, written for this page — never a client's project.
AI-generated
- Trusts the client-supplied MIME type and extension
- No size limit, so one request can fill the disk
- Original filename used as the path —
../included
Human-reviewed
- Type confirmed by reading the file's magic bytes
- Hard size limit enforced before anything is written
- Random filename, correct extension, stored outside the executable path
Check your own
How to tell in two minutes
You don't need us to run these. If any of them come back the wrong way, you have this problem.
- Rename a text file to
test.pngand upload it. If it is accepted, only the extension is being checked. - Try a large file — 100 MB or so. A server that accepts it will accept a thousand of them.
- Look at where files land. If uploads sit in a folder your web server executes, that is the serious version of this bug.
- Check the stored path includes the user ID or a random component. Predictable paths let one user overwrite another's file.
Found it in your project? Fixing this one properly usually takes an engineer under an hour. Finding the other nine takes longer — which is what the free health check is for.
Get my free health checkRelated