File Uploads: A High-Risk Feature
File upload functionality is one of the most security-sensitive features in web applications. Every uploaded file is potentially malicious — it could be a script disguised as an image, a zip bomb designed to crash the server, or a file with a crafted name designed to exploit the file system.
Testing file uploads requires a combination of functional testing, security testing, and usability testing.
File Type Validation
Client-Side Validation
The accept attribute on file inputs restricts which files the user can select:
<input type="file" accept=".jpg,.jpeg,.png,.gif" />
<input type="file" accept="image/*" />
Testing client-side validation:
- Select a valid file type — should be accepted
- Try to select an invalid file type — should be rejected or greyed out
- Bypass the accept attribute (rename a .exe to .jpg) — should still be caught by server
Server-Side Validation
The server must validate the actual file content, not just the extension:
| Test Case | File | Expected |
|---|---|---|
| Valid image | photo.jpg (real JPEG) | Accept |
| Wrong extension | photo.txt (real JPEG renamed) | Reject or accept based on content |
| Fake extension | malware.jpg (actually an .exe) | Reject — content does not match |
| Double extension | image.jpg.php | Reject |
| Null byte in name | image.jpg%00.php | Reject |
| SVG with JavaScript | vector.svg (contains <script>) | Sanitize or reject |
| HTML disguised as image | page.html renamed to page.jpg | Reject |
File Size Testing
| Test Case | Expected |
|---|---|
| File under size limit | Accept and upload successfully |
| File at exact size limit | Accept (boundary value) |
| File 1 byte over limit | Reject with clear error message |
| Very large file (1GB+) | Reject quickly, not after long upload |
| Empty file (0 bytes) | Reject or accept per specification |
| Multiple files near total limit | Handle correctly |
Performance consideration: Size validation should happen on the client side to prevent users from waiting through a long upload only to be told the file is too large.
Upload Functionality Testing
Progress and Feedback
- Does a progress bar or indicator appear during upload?
- Is the percentage accurate?
- Can the user cancel an in-progress upload?
- What happens if the user navigates away during upload?
- Does the upload resume after a network interruption?
Multi-File Uploads
- Can multiple files be selected at once?
- Is there a maximum number of files?
- Can files be removed individually before submission?
- Does the total size of all files respect the limit?
- What is the order of upload — sequential or parallel?
Drag and Drop
- Can files be dragged onto the upload area?
- Does the drop zone highlight when a file is dragged over it?
- Are dragged files validated the same as selected files?
- What happens when non-file items are dragged (text, URLs)?
Special Characters in Filenames
Test uploading files with these filename patterns:
- Spaces:
my document.pdf - Unicode:
документ.pdf,档案.pdf - Special characters:
file (1).jpg,résumé.doc - Very long filenames: 255+ characters
- No extension:
README - Multiple dots:
my.file.name.v2.pdf - Reserved names (Windows):
CON.txt,NUL.jpg,PRN.doc
Security Testing for File Uploads
Executable File Upload
Attempt to upload files that could be executed on the server:
.php,.asp,.aspx,.jsp— server-side scripts.html,.htm— could contain JavaScript.svg— can contain embedded scripts.exe,.bat,.sh— system executables
The server must reject or sanitize these. If uploaded, they should not be executable.
Path Traversal
Test filenames designed to escape the upload directory:
../../../etc/passwd..\\..\\..\\windows\\system.ini....//....//etc/passwd
The server must sanitize filenames and never use user-provided paths directly.
Zip Bomb Testing
A zip bomb is a small compressed file that expands to enormous size:
- Upload a zip file that is 1 KB compressed but expands to 1 GB+
- The server should detect and reject decompression bombs
- Monitor server resources during upload processing
Exercise: File Upload Security Audit
Test a file upload feature:
- Basic functionality: Upload valid files of each accepted type
- Type bypass: Rename an executable to have an image extension — is it rejected?
- Size limits: Upload a file just over the limit — is the error message helpful?
- Special filenames: Upload files with unicode, spaces, and special characters
- Multiple files: Upload the maximum number of files, then try one more
- Cancel and retry: Start an upload, cancel it, then try again
- Network failure: Start an upload, then disconnect the network — what happens?
- Concurrent uploads: Upload files in multiple tabs simultaneously
Document findings:
| Test | Result | Bug? | Severity |
|---|---|---|---|
| .exe renamed to .jpg | Uploaded successfully | Yes | Critical |
| 100 MB file (limit: 10 MB) | Error only after full upload | Yes | Medium |
Filename with ../ | 500 server error | Yes | Critical |
| Cancel upload | Progress bar freezes | Yes | Low |
Post-Upload Testing
After a file is uploaded, verify:
- The file can be downloaded and is not corrupted
- The file is stored securely (not in a publicly accessible directory)
- The file URL is not predictable (prevents enumeration)
- Image files are served with correct Content-Type headers
- Downloaded files have
Content-Disposition: attachmentfor non-viewable types - Old/replaced files are properly deleted
Key Takeaways
- File uploads are high-security-risk features requiring thorough testing
- Server-side validation must check actual file content, not just extensions
- Size validation should happen client-side to avoid frustrating long uploads
- Test filenames with special characters, unicode, and path traversal patterns
- Uploaded files must not be executable on the server
- Multi-file, drag-and-drop, progress, and cancellation all need testing
- Post-upload: verify files are stored securely and served with correct headers