WordPress.org

Ready to get started?Download WordPress

Codex

Attention Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Difference between revisions of "htaccess for subdirectories"

(Effectively removing the dot from the article name)
 
m (Securing individual directories with .htaccess)
Line 16: Line 16:
 
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.
 
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:
+
The following snippet of code prevents any files other than .jpeg, .jpg, .png. or .gif to be served from the directory:
   
 
<pre>
 
<pre>
Line 25: Line 25:
 
</pre>
 
</pre>
   
The following code will prevent .pl, .cgi or .php scripts from being executed; instead, they will display as plain text inside the browser window:
+
  +
This example uses the FilesMatch directive to specifically allow these types of files to be accessed.
   
 
<pre>
 
<pre>
AddType text/plain .pl
+
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$">
AddType text/plain .cgi
+
Allow from All
AddType text/plain .php
+
</FilesMatch>
 
</pre>
 
</pre>
   
Here's another way to display scripts as plain text instead of executing them:
+
  +
The following code will prevent .pl, .cgi or .php scripts from being executed; instead, they will display as plain text inside the browser window:
   
 
<pre>
 
<pre>
RemoveHandler cgi-script .pl .py .cgi
+
AddType text/plain .pl .cgi .php
 
</pre>
 
</pre>
   
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.
+
You should combine that method with these directives to serve scripts as plain text instead of executing them:
   
<pre style="font-size: 0.92em;">
+
<pre>
AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
 
 
Options -ExecCGI
 
Options -ExecCGI
  +
RemoveHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
  +
</pre>
  +
  +
  +
And the safest way is the following, which removes all handlers and actions normally associated with these extensions.
  +
  +
<pre>
  +
<FilesMatch "\.(php|pl|py|jsp|asp|htm|shtml|sh|cgi)$">
  +
ForceType text/plain
  +
</FilesMatch>
 
</pre>
 
</pre>
   
''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.
 
   
   
  +
{{{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, and hopefully for just a temporary amount of time. Give the .htaccess file the lowest possible permission setting that will still work for your server. Try ''600, 604 640, 644, 646, 666''.}}
   
 
== Further Reading ==
 
== Further Reading ==

Revision as of 08:50, 8 December 2008

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 served from the directory:

<Files ^(*.jpeg|*.jpg|*.png|*.gif)>
   order deny,allow
   deny from all
</Files>


This example uses the FilesMatch directive to specifically allow these types of files to be accessed.

<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$">
Allow from All
</FilesMatch>


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 .cgi .php

You should combine that method with these directives to serve scripts as plain text instead of executing them:

Options -ExecCGI
RemoveHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi


And the safest way is the following, which removes all handlers and actions normally associated with these extensions.

<FilesMatch "\.(php|pl|py|jsp|asp|htm|shtml|sh|cgi)$">
ForceType text/plain
</FilesMatch>


{
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, and hopefully for just a temporary amount of time. Give the .htaccess file the lowest possible permission setting that will still work for your server. Try 600, 604 640, 644, 646, 666.

Further Reading

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)

This article is marked as in need of editing. You can help Codex by editing it.