WordPress:Htaccess for subdirectories
The Problem
On computer filesystems, files and directories have a set of permissions assigned to them that specify who can read, edit or execute each file. This permissions system is one of the basic concepts that provide security for your web site. A default WordPress installation comes with permissions settings for its files and folders (i.e. directories) that can be regarded as very secure. However, there is a trade-off between security and functionality: Some wordpress plugins require more lenient security settings for the directories they read from or write to in order to work properly.
An Example
The ImageManager plugin provides a sophisticated interface for uploading, editing and managing image files for WordPress. It writes to and reads from a base image directory which can be set up in the plugin's options panel. This directory needs to be world-writeable (chmod 777) in order to work properly. However, any directory whose permissions have been set to '777' present a (real) security hole: a malicious visitor could upload a script to that directory and hack your site.
The Question
How can you secure your WordPress installation while still enjoying the extended functionality that WordPress plugins provide?
Securing individual directories with .htaccess
One possible solution for this problem is provided by .htaccess. You can add a .htaccess file to any directory that requires lenient permissions settings (such as 760, 766, 775 or 777). You can prevent the execution of scripts inside the directory and all its sub-directories. You can also prevent any files other than those of a certain type to be written to it.
The following snippet of code prevents any files other than .jpeg, .jpg, .png. or .gif to be uploaded to the directory:
<Files ^(*.jpeg|*.jpg|*.png|*.gif)> order deny,allow deny from all </Files>
The following code will prevent .pl, .cgi or .php scripts from being executed; instead, they will display as plain text inside the browser window:
AddType text/plain .pl AddType text/plain .cgi AddType text/plain .php
Here's another way to display scripts as plain text instead of executing them:
RemoveHandler cgi-script .pl .py .cgi
The following code categorizes all files that end in certain extensions so that they fall under the jurisdiction of the -ExecCGI command (removes the ability to execute scripts), which also means -FollowSymLinks.
AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi Options -ExecCGI
Please note: From a security standpoint, even a small amount of protection is preferable to a world-writeable directory. Try less permissive settings like 766, then 775 and only use 777 if necessary. Make sure that the .htaccess file itself has a chmod of 644.
Further Reading
WordPress:Changing File Permissions (WordPress Codex)
chmod and file permissions (WordPress Codex)
[ chmod tutorial]
Blocking traffic to your web site (Tips & Scripts.com)
Apache Tutorial: htaccess files (Apache Server Documentation)
Authentication, Authorization and Access Control (Apache Server Documentation)
The allow, deny and order directives (Apache Server Documentation)
Hardening htaccess Robert Hansen, SecurityFocus
The ultimate htaccess Guide (askapache.com)
Relevant Forum Threads
Securing 777 directories (WordPress forum)
Using .htaccess to secure 777 directories (WordPress forum)
Preventing hot-linking with .htaccess (WordPress forum)
Using htaccess to secure image directory (ImageManager forum)