Upload Protection: Control What Comes In
The /uploads folder is where images, documents, and files uploaded by users are stored. It's a perfect entry point for attackers because:
- It's publicly accessible
- Many users can upload files
- If unprotected, a user can upload a .php file that gets executed
SeenSecure's Upload Protection checks EVERY file that gets uploaded: its type, size, content. If something suspicious is detected, it's always logged and, if the firewall is in blocking mode, also rejected instantly.
Threats Against Uploads
1. Uploading Executable Files
Attacker uploads a .php file that, when accessed, executes malicious code.
upload.php → contains PHP code → attacker executes commands on your server
2. Extension Spoofing
Attacker uploads .php but renames it to .jpg to pass basic validations.
malware.php → renamed to → photo.jpg (but is still PHP)
3. Polymorphism
Malware that mutates its code to evade antivirus detection. Every copy is different.
4. ZIP Bomb File
A compressed file that contains 1000GB of data. When decompressed, it uses up all the server's storage.
5. Metadata Injection
Malware inserted into image metadata (EXIF). If WordPress processes the image without sanitizing it, code gets executed.
| Attack Type | Danger Level | Detection |
|---|---|---|
| Direct .php upload | ⭐⭐⭐⭐⭐ | Very easy |
| Fake extension | ⭐⭐⭐⭐ | Easy |
| Polymorphism | ⭐⭐⭐ | Difficult |
| Metadata | ⭐⭐⭐ | Very difficult |
What Does Upload Protection Protect?
Every file uploaded to your WordPress goes through 6 independent checks before it gets saved —if any of them fails, the attempt is logged and, with the firewall in blocking mode, rejected. It isn't a whitelist that only allows certain formats — it's a configurable blocklist of what's dangerous, combined with checks that examine the file's actual content, not just its name. For each layer we explain what it's for, why an attacker uses it, and how SeenSecure acts to stop it.
1. File Size Limit
What this protection is for: every uploaded file consumes disk space on your server. Without a limit, any user with upload permission — or a poorly protected public form, like a contact plugin or a comment form with attachments — could send disproportionately large files, exhausting available storage or keeping the server busy while it processes the upload.
Why an attacker attempts it: uploading disproportionately large files is a simple form of denial-of-service (DoS) attack: filling the disk until WordPress can no longer write anything else — not even save a post or generate a backup — or forcing the server to spend resources repeatedly processing giant files.
Real example: an avatar upload form, meant for images of a few hundred KB, receives an 800MB file sent repeatedly from several IPs. Without a size limit, each attempt is accepted and processed until disk space runs out.
How it works: SeenSecure compares the received file's size against a single limit in megabytes that you configure (10MB by default, applied to any file type). If it's exceeded, the attempt is logged and, when the firewall is in blocking mode, the upload is rejected before it's permanently saved to your media library.
2. Blocked Extensions (Blocklist)
What this protection is for: a file's extension (.php, .exe, .jpg...) tells the server how to treat it. Some extensions — especially ones a PHP-enabled server knows how to execute as code — are dangerous if they end up inside a publicly accessible folder like /wp-content/uploads: if someone accesses that URL directly, the server doesn't just display the file, it runs it.
Why an attacker attempts it: if an attacker manages to upload a file with an executable extension (typically .php) to a publicly accessible folder, they get what's known in security as a "web shell": a permanent entry point from which they can run commands, read and modify files, or install more malware, without ever needing to authenticate to WordPress again.
Real example: an attacker tries to upload a file called shell.php through a document upload form. SeenSecure compares its extension against the blocked extensions list — which includes variants like .php3, .phtml, and .phar as well as executables like .exe, .sh, and .bat — and rejects the upload before the file gets saved.
How it works: unlike a whitelist (which would only allow certain extensions and block everything else), SeenSecure uses a configurable blocklist of known dangerous extensions — PHP variants, executables, server scripts — that you can customize by adding or removing extensions from the panel based on what your site needs to upload. Removing the default executable extensions from the list isn't recommended unless you know exactly what you're doing.
3. Blocked MIME Types and Real Content Verification
What this protection is for: a file's extension is just a label in its name — anyone can rename malware.php to photo.jpg without its content changing by a single byte. The MIME type describes what the file actually is, and verifying it prevents a file from slipping through just because it wears the "right" label.
Why an attacker attempts it: renaming the extension is the first trick any attacker tries once they discover there's a blocked extensions list — it's fast, requires no advanced skills, and works against systems that only look at the filename without examining what's inside.
Real example: a file called image.gif is uploaded with the MIME type declared by the browser (image/gif), but examining its actual first bytes the server determines it's really application/x-php. SeenSecure detects the mismatch and rejects the file, even though the name and declared header looked harmless.
How it works: SeenSecure applies two related checks: it compares the MIME type declared on upload against its list of blocked types, and it also uses a system-level check (via PHP's fileinfo library) that examines the file's actual content to determine its real type, regardless of what its name or declared header say. If that real type matches a blocked one, WordPress rejects the file even if its extension looked harmless.
4. Content Scanning
What this protection is for: even a file with a seemingly correct extension and MIME type can carry malicious code hidden inside it — for example, PHP code appended to the end of a valid image, so the file still displays as a normal image while also being interpretable as a script if someone gets the server to execute it. Content scanning adds one last layer that examines what's actually inside the file.
Why an attacker attempts it: combining a legitimate file (an image that displays and loads normally) with hidden executable code lets it pass superficial extension and declared-type checks, and it only reveals itself as malicious if the attacker, through some other vulnerability, gets the server to interpret it as code instead of displaying it as an image.
Real example: a file photo.jpg passes the extension and MIME checks because its header is a valid image, but it also contains a <?php tag followed by a function capable of running system commands. SeenSecure reads the file's content, finds that fragment, and rejects it.
How it works: SeenSecure examines the uploaded file's content looking for patterns characteristic of malicious executable code — functions and structures that have no legitimate reason to appear inside a normal image, PDF, or document. It's not an antivirus with known-virus signatures, nor an isolated execution environment ("sandbox"): it's an analysis of the content looking for suspicious fragments, without ever executing the file.
5. Double Extension Detection
What this protection is for: some misconfigured servers, when they see a filename like image.jpg.php, only process the last extension they recognize — and if that final part is .php, they run it as PHP code regardless of the rest of the name "looking" like an image. This protection detects that suspicious naming pattern.
Why an attacker attempts it: the double extension trick tries to confuse both basic validation systems (that only check whether the name "contains" .jpg somewhere) and the server's own configuration, betting that it will execute the real final extension (.php) while the name visually looks like a harmless image file.
Real example: an attacker names their file backdoor.jpg.php. A naive filter that only checks whether the name "contains" .jpg would let it through; SeenSecure splits the full name by its dots and checks each intermediate fragment against the dangerous extensions list, detects the .php, and rejects the file.
How it works: SeenSecure analyzes the file's full name, not just its final extension, looking for any known dangerous extension at any position in the name — not just at the end — to catch this kind of camouflage before the file gets saved.
6. Null Byte Detection
What this protection is for: the null byte is a special character that, in many low-level programming languages, means "end of the text string." It's an old but still effective technique against poorly written code to trick filename validation, making the system "see" a different name than the one actually used when the file gets saved.
Why an attacker attempts it: by inserting a null byte between the executable part of a filename and a seemingly harmless extension, an attacker tries to make validation stop at the "safe" extension (everything before the null byte) while the underlying file system keeps processing the full name, including the real, dangerous extension that follows.
Real example: a file is named shell.php%00.jpg (or its equivalent with the actual null byte instead of its text representation). A vulnerable validator that stops at the first extension it "sees" would treat it as a harmless .jpg; SeenSecure detects the presence of the null byte in the name and rejects it directly.
How it works: SeenSecure checks whether the filename contains a null byte, both in its actual binary form and in its text representation (%00), and rejects any upload that contains it, without needing to figure out which extension "wins" on a misconfigured system.
How to Configure Upload Protection
Step 1: Enable Protection
SeenSecure > Firewall > "Uploads" tab > turn on "Enable Upload Protection"
Step 2: Review and Customize Blocked Extensions
By default, the list already includes the most dangerous extensions (PHP variants, executables, server scripts) in a comma-separated text field you can edit freely. It isn't a list of "the only things allowed": any extension not on this list is still accepted normally, so it only makes sense to add formats here that you know you don't need and want to explicitly block.
Step 3: Set the Size Limit
It's a single limit in megabytes applied to any uploaded file, regardless of type. The default is 10MB; setting it to 0 makes it fall back to your WordPress/hosting's general upload limit instead. Adjust the number based on what you actually upload to your site (for example, raise it if you need to accept videos or large PDFs).
Step 4: Enable the Advanced Layers
- Scan file content: looks for PHP code, JavaScript, and malicious patterns inside files, even if their extension and declared type look harmless.
- Detect double extension: blocks files like
image.jpg.php. - Detect null byte: blocks files with a null byte in the name, a classic bypass technique.
Recommendation: all 3 are enabled by default and should stay that way — each covers a different angle of attack that the other layers don't cover on their own.
Step 5: Understand the Firewall Mode (Monitoring vs. Blocking)
What it does: Upload Protection doesn't have its own "reject / quarantine / notify" switch: its behavior on a violation depends on the Firewall's overall mode (SeenSecure > Firewall > Mode). In Monitoring, every suspicious attempt is logged but the file is still accepted. In Protection or Strict, the file is rejected on the spot. If you enable Upload Protection but the global firewall stays in Monitoring, you'll see attempts in the log without any actually being blocked — check both settings together.
Step 6: Review the Upload Activity Log
The same Upload Protection tab includes a table with the latest rejected or logged uploads: time, filename, reason (blocked extension, blocked MIME, double extension, null byte, malicious content, or size exceeded), whether it was blocked or only monitored, the source IP, and the user's role. A "Clear log" button lets you empty that history whenever you want.
Best Practices
For Administrators
- Keep the list of allowed extensions as small as possible
- Review rejected uploads weekly (SeenSecure > Firewall > Uploads tab)
- If there are many legitimate rejections, adjust the configuration (don't disable it)
- Educate users: not everyone understands why a file gets rejected
For Users
- If your file is rejected, it's for a security reason
- If you need to upload that type of file, contact the admin
- Compress large images before uploading (also improves speed)
- Use safe file names (no unusual characters)
What to Do if Someone Tries to Upload Malware
- SeenSecure rejects it automatically
- Check the log: SeenSecure > Firewall > Uploads tab
- If it's a legitimate user who didn't know, explain it to them
- If there are multiple attempts from the same IP, consider a temporary block
Frequently Asked Questions
If I reject SVG, am I missing functionality? Not much. SVG is very versatile but is also an attack vector. If you need it, use the "safe" version that SeenSecure allows.
Does it slow down uploads? Slightly. Content analysis adds 1-2 seconds. But the security is worth it.
What happens if I accidentally upload a forbidden file? It gets rejected, you see an error message, and you try again with another file. Nothing dangerous.
Can I allow only Admins to upload videos? Upload Protection applies the same extension, size, MIME type, and content rules to all users equally — it doesn't have role-based permission settings. Restricting who can upload video files is a matter of WordPress roles and capabilities (or a dedicated permissions plugin), not this specific protection.