What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
To secure /wp-content/uploads, keep the directory readable over HTTP(S) and writable by WordPress, but deny PHP execution inside it at the web-server layer. On Nginx, add a location rule in the server configuration. On Apache or LiteSpeed, use a .htaccess or virtual-host rule. Then verify that a harmless PHP test file is denied while JPG, PNG, PDF and other legitimate media still load.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
What the uploads directory does—and what security must preserve
WordPress normally stores uploaded images, videos, documents and generated media variants under /wp-content/uploads, often separated into year-and-month folders. Browsers need to request those files directly, so making the entire directory inaccessible will break images, downloads, thumbnails, feeds and editor previews.
As an Amazon Associate I earn from qualifying purchases.
WordPress also needs a server-side process with write access there when an administrator or editor uploads media. Those two requirements are different from PHP execution. A process may be allowed to create a file while the web server refuses to execute a PHP request for that file. The useful security boundary is therefore: deliver ordinary media, permit the expected write operation, and reject script execution.
An uploaded PHP file is dangerous because a successful request can run code with the privileges of the web process. Blocking execution in the upload location limits the damage from a vulnerable plugin, a compromised account or an upload validation bypass. This control does not replace patching or account security; it removes one particularly valuable execution path.
#1 Best Overall
Choose the rule for the server actually serving the site
| Server | Where the control belongs | Normal media behavior | Access normally required | Multisite consideration |
|---|---|---|---|---|
| Nginx | Relevant server configuration, usually a server block or included configuration file |
Files such as JPG, PNG, PDF and video remain available unless another rule blocks them | Permission to edit server configuration and reload or restart Nginx, or a host that will apply the change | Cover both uploads and the documented files path where the installation uses it |
| Apache | An .htaccess file in the uploads directory or the applicable virtual-host configuration |
Only PHP requests are denied by the shown rule; ordinary media is unaffected | Permission to use per-directory overrides, or virtual-host access if overrides are restricted | Check the network’s upload and rewrite layout before applying a blanket path rule |
| LiteSpeed | Usually Apache-compatible .htaccess controls, subject to the host’s configuration |
Expected media should continue to load | Ability to edit the applicable file and confirm which directives the host permits | Confirm the host’s mapping for multisite files and uploads |
| IIS or another server | The server’s own request-filtering or handler configuration | Must be tested rather than assumed | Server or hosting-panel access, or help from the host | Use the site’s actual URL-to-file mapping |
Nginx has no directory-level file equivalent to Apache’s .htaccess. WordPress’s Advanced Administration Handbook states: “With Nginx there is no directory-level configuration file like Apache’s .htaccess or IIS’s web.config files.” A rule pasted into an uploads .htaccess file therefore has no effect on an Nginx site.
Identify the real uploads path before editing anything
- Confirm the document root. The public directory may be named
public_html,www,htdocsor something else. The filesystem path is not necessarily the same as the URL path. - Check WordPress’s media settings. A standard installation uses
/wp-content/uploads, but a multisite network or a media-storage plugin can use a different location or URL. - Determine the web server. Ask the host or inspect the hosting control panel. Do not select an Nginx rule merely because an Apache-style file exists in the project.
- Record ownership and permissions. Note which user owns the directory and which account runs PHP. This information is needed if uploads stop working after a permissions change.
- Make a recoverable copy of the file you will edit. Save the current server block or
.htaccesscontents outside the web root before changing it.
If the site uses custom storage, the correct protection target is the directory that is both publicly mapped and capable of receiving untrusted uploads. Protecting an unused default folder does not secure the active storage location.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallBlock PHP execution on Nginx
Add the rule to the server configuration
Place this location block in the Nginx configuration that handles the WordPress site:
Rank #2
location ~* /(?:uploads|files)/.*.php$ {
deny all;
}
The expression matches PHP requests below paths containing uploads or files, and deny all prevents the request from being served. The inclusion of files matters for WordPress multisite configurations that use that path. Apply the rule in the relevant server context rather than in an uploads directory.
Deploy without losing the existing WordPress configuration
- Open the active server block or included site configuration, not an unused example file.
- Insert the location rule at the server-configuration level used by the site’s existing WordPress rules.
- Run the host’s configuration validation command or use its control-panel test before reloading. The exact command and reload method vary by host, so follow that host’s documented procedure.
- Reload Nginx only after validation succeeds. A syntax error can prevent the server from reloading and may take the site offline until the configuration is corrected.
- Perform the functional test described below from an external HTTP(S) request.
Do not try to solve this with an uploads .htaccess file on Nginx; Nginx does not read it for directory access control.
Check multisite and rewrite interactions
Network installations can use different URL forms for uploaded files, and WordPress documents separate rewrite and server-configuration models for multisite. Verify an actual media URL from each relevant site and test the path used for network files. A rule that protects only the single-site uploads pattern may leave a network-specific files path uncovered; the example above includes both names for that reason.
Block PHP execution with Apache or LiteSpeed
Use an uploads-directory .htaccess file
In Apache-compatible hosting, create or edit the .htaccess file in the uploads directory and add:
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
This denies requests for files whose names end in .php within the directory governed by the file. It does not deny JPG, PNG, PDF, audio, video or other non-PHP media. The host must permit the FilesMatch and Require directives in per-directory overrides; some managed environments disable them.
Keep custom rules outside WordPress’s generated block
If you place the protection in the site’s main .htaccess file, keep it outside the # BEGIN WordPress and # END WordPress section. WordPress may regenerate that section when permalink settings are saved, overwriting edits made inside it. An uploads-directory file is easier to isolate, while a virtual-host rule is preferable when the host restricts .htaccess overrides.
Rank #4
Confirm the Apache version and host policy
The shown syntax uses Apache’s authorization directive style. Older or specially configured servers may require a host-specific equivalent. Ask the host which directives are allowed rather than substituting a rule copied from an unrelated Apache version. LiteSpeed commonly accepts Apache-style controls, but the active configuration still determines the result.
Free tools Windows power users keep installed
One-click scans. No signup required.
Verify that the control works
A configuration change is not complete until it has been tested from the same HTTP(S) path an attacker would use.
- Identify the active path. Use the real document root and URL mapping, including a multisite or custom-storage variation.
- Create a harmless test file. In the protected directory, create
security-test.phpcontaining only plain text, such asuploads execution test. Do not place credentials, shell commands or diagnostic code in it. - Request the file over HTTP(S). Visit its complete URL in a browser or use an HTTP client from outside the server.
- Confirm execution is denied. A 403 or 404 response is an expected successful outcome. The browser must not display the file’s PHP output, and the server must not process it as a script.
- Test representative media. Open a JPG or PNG, a PDF if the site serves documents, and a normal video or audio URL when those media types are part of the site.
- Remove the test file immediately. Leaving even harmless executable-looking files in a public directory creates confusion during later audits.
- Inspect the directory and logs. Look for unexpected executable files, ownership changes and repeated denied requests. Re-test after a hosting migration, PHP change, web-server change or cache configuration change.
If the PHP file returns its source code, downloads, displays a PHP-generated response or otherwise executes, the rule is not active at the request path being tested. Stop treating the directory as protected until the server configuration is corrected.
Best Value
Keep uploads writable without making them unsafe
Use least-privilege permissions
Do not set the uploads tree to world-writable 777 as a troubleshooting shortcut. WordPress’s hardening and permissions guidance treats broadly writable locations as an attack surface. Set ownership and write permissions so the PHP process can create the files WordPress needs, while unrelated users cannot modify the tree.
Permission numbers alone do not explain every hosting setup. Shared hosting, PHP-FPM pools, containers and deployment accounts can use different users and groups. If uploads fail after tightening permissions, check the PHP process’s effective user, directory traversal permissions on parent folders and the ownership of existing year/month directories. Correct the ownership or group arrangement instead of reopening the directory to everyone.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteSeparate execution control from file validation
The web-server rule is a backstop, not permission to accept arbitrary uploads. WordPress, its plugins and any custom upload endpoint should still validate file types, enforce authentication and limit who can upload. Review whether a plugin writes files outside the normal uploads tree; that location needs equivalent protection if it is publicly reachable.
Add defense in depth around the execution rule
- Update WordPress core, themes and plugins. Remove abandoned or unused plugins rather than leaving their code reachable.
- Disable dashboard file editing when appropriate. Setting
DISALLOW_FILE_EDITinwp-config.phpremoves the built-in editor for themes and plugins. It does not replace upload-directory protection. - Use non-privileged service accounts. Run the site and web server with the least privilege compatible with the hosting model.
- Consider a security plugin, reverse-proxy WAF or hosting firewall. These layers can detect malicious requests and abuse, but they do not replace denying PHP execution in uploads.
- Review logs and unexpected files. A newly appearing executable file, repeated requests for PHP under uploads or unexplained permission changes warrants investigation.
Defense in depth reduces the chance that one missed update, credential compromise or configuration mistake becomes arbitrary code execution. Each layer has a different job; none makes the others unnecessary.
Troubleshoot common failures
| Symptom | Likely cause | What to check |
|---|---|---|
| PHP test file executes | The rule is in the wrong server, wrong path or an inactive configuration file | Confirm the active document root, virtual host and server type; reload the configuration and inspect the response again |
| Images and PDFs return 403 | A broader deny rule or directory restriction is blocking all files | Check for a parent-directory authorization rule and narrow the control to PHP requests |
| New uploads fail in WordPress | Filesystem ownership or write permission was changed | Check the PHP process user, group membership and parent-directory traversal permissions; do not use 777 as the default fix |
| Apache rule has no effect | Overrides are disabled, or the file is not in the directory serving the URL | Ask the host whether FilesMatch and Require are permitted and verify the URL-to-filesystem mapping |
| Nginx rule has no effect | The rule was put in .htaccess or an unused server block |
Move it to the active Nginx server configuration, validate it and reload Nginx |
| One multisite site’s files remain executable | The network uses a different files or upload URL pattern |
Capture a real URL from that site and extend the server rule only after confirming the mapping |
| Media works in a browser but fails through a cache or CDN | A proxy or cache has its own access rule or stale response | Test the origin and public URL separately, purge the relevant cache and retain the origin execution denial |
Operational checklist
- Document the actual public uploads path and any custom or multisite storage paths.
- Record whether the site runs Apache, LiteSpeed, Nginx or IIS before selecting a directive.
- Back up the configuration file, then add the narrow PHP-denial rule at the correct server layer.
- Validate and reload the server according to the host’s procedure.
- Request a harmless PHP file and confirm a 403 or 404 rather than execution.
- Open representative images, documents and other required media.
- Delete the test file and inspect the directory for unexpected executables.
- Review ownership and permissions, keeping write access limited to the accounts that need it.
- Repeat the test after migrations, PHP or web-server upgrades, hosting changes and significant caching changes.
Key decision
The highest-value change is simple: disable PHP execution in every publicly reachable upload location while leaving ordinary media delivery intact. Nginx requires a server-level location rule; Apache and compatible LiteSpeed deployments can usually use a narrowly scoped .htaccess or virtual-host rule. The protection is credible only when a real HTTP test proves the PHP file is denied and normal media still works.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




