As discussed, it's important to protect your site by setting proper file permissions on the server. This can be tricky for certain directories such as
/backups/, which need to be writable by the server in order for things like uploads, upgrades, and backups to work.
On the one hand, you want the most restrictive permissions possible for security reasons, and in most cases the default/recommended settings for directories such as
/uploads/ work just fine. On the other hand, if your directory permissions are too restrictive, things like media-uploads stop working.
The good news is that we can have the best of both worlds: solid security for writable directories and suitable file-permissions for working uploads, upgrades, and backups. In this tutorial, you'll learn how to use .htaccess to secure WordPress’
/uploads/ directory or just about any other directory, WordPress or otherwise.
Securing directories with .htaccess
In my experience studying server logs, WordPress’
/uploads/ directory is heavily targeted by malicious scripts and bots. Unfortunately, some server configurations require
777 permissions in order for stuff like Media Uploads to work. Of course, that's never a good idea, so let's lock down those vulnerable directories with a bit of .htaccess.
Note that this technique is written for use in .htaccess files, but is better implemented via Apache's main configuration file (httpd.conf). If you don't have access to configuration files or prefer to localize via .htaccess, the following technique will make it happen.
Create an .htaccess file for your
/uploads/ directory (or use existing file if present). In it, place the following code and upload to your server:
# secure uploads directory <Files ~ ".*\..*"> Order Allow,Deny Deny from all </Files> <FilesMatch "\.(jpg|jpeg|jpe|gif|png|tif|tiff)$"> Order Deny,Allow Allow from all </FilesMatch>
This denies access to all files but then allows access only to the specified types of images. If you're working with other media types such as .zip, .mp3, .mov, or whatever, simply edit the
FilesMatch pattern like so:
Likewise you can remove anything that you won't be using. This is the key to implementing this technique in other directories such as
/backup/, and so forth. Once in place, this technique prevents bad guys from injecting any PHP or other scripts, but allows images (and/or other specified file types).
Other things to try
If you're trying to get media-uploads to work but don't want to go all
777 on the server, here are some other, more round-about things to try:
- experimenting with incrementally more secure permissions until something works
- disabling PHP Safe Mode
- unchecking the auto-organization year/month option
- trying different file paths
- switching hosts if possible
I've experimented with all of these tactics in various server environments, but it's generally hit-or-miss — works or it doesn't. Some alternate solutions/workarounds aren't as secure as others, so if you're stuck with
777 permissions, the previous .htaccess technique will help secure your
/uploads/ directory against malicious scripts and other nefarious behavior.
Shameless plug! If you enjoy .htaccess techniques like the one in this article, check out my new book, .htaccess made easy — Thank you!