Here are some specific htaccess examples taken mostly from my WordPress Password Protection plugin, which does alot more than password protection as you will see from the following mod_rewrite examples. These are a few of the mod_rewrite uses that BlogSecurity declared pushed the boundaries of Mod_Rewrite! Some of these snippets are quite exotic and unlike anything you may have seen before, also only for those who understand them as they can kill a website pretty quick.
Enable the DirectoryIndex Protection, preventing directory index listings and defaulting. [Disable]
Options -Indexes DirectoryIndex index.html index.php /index.php
Requires a valid user/pass to access the login page[401]
<Files wp-login.php> Order Deny,Allow Deny from All Satisfy Any AuthName "Protected By AskApache" AuthUserFile /web/askapache.com/.htpasswda1 AuthType Basic Require valid-user </Files>
Requires a valid user/pass to access any non-static (css, js, images) file in this directory.[401]
Options -ExecCGI -Indexes +FollowSymLinks -Includes DirectoryIndex index.php /index.php Order Deny,Allow Deny from All Satisfy Any AuthName "Protected By AskApache" AuthUserFile /web/askapache.com/.htpasswda1 AuthType Basic Require valid-user <FilesMatch "\.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$"> Allow from All </FilesMatch> <FilesMatch "(async-upload)\.php$"> <IfModule mod_security.c> SecFilterEngine Off </IfModule> Allow from All </FilesMatch>
Denies any Direct request for files ending in .php with a 403 Forbidden.. May break plugins/themes [401]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wp-content/.*$ [NC] RewriteCond %{REQUEST_FILENAME} !^.+flexible-upload-wp25js.php$ RewriteCond %{REQUEST_FILENAME} ^.+\.(php|html|htm|txt)$ RewriteRule .* - [F,NS,L]
Denies any Direct request for files ending in .php with a 403 Forbidden.. May break plugins/themes [403]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wp-includes/.*$ [NC] RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ /wp-includes/js/.+/.+\ HTTP/ [NC] RewriteCond %{REQUEST_FILENAME} ^.+\.php$ RewriteRule .* - [F,NS,L]
Block common exploit requests with 403 Forbidden. These can help alot, may break some plugins. [403]
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ ///.*\ HTTP/ [NC,OR] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\?\=?(http|ftp|ssl|https):/.*\ HTTP/ [NC,OR] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\?\?.*\ HTTP/ [NC,OR] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(asp|ini|dll).*\ HTTP/ [NC,OR] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(htpasswd|htaccess|aahtpasswd).*\ HTTP/ [NC] RewriteRule .* - [F,NS,L]
Denies any request for static files (images, css, etc) if referrer is not local site or empty. [403]
RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteCond %{HTTP_REFERER} !^https://www.askapache.com.*$ [NC] RewriteRule \.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$ - [F,NS,L]
Denies any request not using GET,PROPFIND,POST,OPTIONS,PUT,HEAD[403]
RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST|PROPFIND|OPTIONS|PUT)$ [NC] RewriteRule .* - [F,NS,L]
Denies any POST Request using a Proxy Server. Can still access site, but not comment. See Perishable Press [403]
RewriteCond %{REQUEST_METHOD} =POST RewriteCond %{HTTP:VIA}%{HTTP:FORWARDED}%{HTTP:USERAGENT_VIA}%{HTTP:X_FORWARDED_FOR}%{HTTP:PROXY_CONNECTION} !^$ [OR] RewriteCond %{HTTP:XPROXY_CONNECTION}%{HTTP:HTTP_PC_REMOTE_ADDR}%{HTTP:HTTP_CLIENT_IP} !^$ RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteRule .* - [F,NS,L]
Denies any POST attempt made to a non-existing wp-comments-post.php[403]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*/wp-comments-post\.php.*\ HTTP/ [NC] RewriteRule .* - [F,NS,L]
Denies any badly formed HTTP PROTOCOL in the request, 0.9, 1.0, and 1.1 only[403]
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .+\ HTTP/(0\.9|1\.0|1\.1) [NC] RewriteRule .* - [F,NS,L]
Denies any request for a url containing characters other than "a-zA-Z0-9.+/-?=&" - REALLY helps but may break your site depending on your links. [403]
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ [a-zA-Z0-9\.\+_/\-\?\=\&]+\ HTTP/ [NC] RewriteRule .* - [F,NS,L]
Denies any POST request that doesnt have a Content-Length Header[403]
RewriteCond %{REQUEST_METHOD} =POST RewriteCond %{HTTP:Content-Length} ^$ RewriteCond %{REQUEST_URI} !^/(wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteRule .* - [F,NS,L]
Denies any POST request with a content type other than application/x-www-form-urlencoded|multipart/form-data[403]
RewriteCond %{REQUEST_METHOD} =POST RewriteCond %{HTTP:Content-Type} !^(application/x-www-form-urlencoded|multipart/form-data.*(boundary.*)?)$ [NC] RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteRule .* - [F,NS,L]
Denies requests that dont contain a HTTP HOST Header.[403]
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteCond %{HTTP_HOST} ^$ RewriteRule .* - [F,NS,L]
Denies obvious exploit using bogus graphics[403]
RewriteCond %{HTTP:Content-Disposition} \.php [NC] RewriteCond %{HTTP:Content-Type} image/.+ [NC] RewriteRule .* - [F,NS,L]
Denies POST requests by blank user-agents. May prevent a small number of visitors from POSTING. [403]
RewriteCond %{REQUEST_METHOD} =POST RewriteCond %{HTTP_USER_AGENT} ^-?$ RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC] RewriteRule .* - [F,NS,L]
Denies any comment attempt with a blank HTTP_REFERER field, highly indicative of spam. May prevent some visitors from POSTING. [403]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*/wp-comments-post\.php.*\ HTTP/ [NC] RewriteCond %{HTTP_REFERER} ^-?$ RewriteRule .* - [F,NS,L]
Denies obvious trackback spam. See Holy Shmoly! [403]
RewriteCond %{REQUEST_METHOD} =POST RewriteCond %{HTTP_USER_AGENT} ^.*(opera|mozilla|firefox|msie|safari).*$ [NC] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.+/trackback/?\ HTTP/ [NC] RewriteRule .* - [F,NS,L]
RewriteEngine On RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f RewriteRule . /script.php
In the case where all URIs should be sent to the same place (including potentially requests for static content) the method to use depends on the type of the handler. For php scripts, use: For other handlers such as php scripts, use:
RewriteEngine On RewriteCond %{REQUEST_URI} !=/script.php RewriteRule .* /script.php
ScriptAliasMatch .* /var/www/script.cgi
RewriteEngine On RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f RewriteCond %{REQUEST_URI} !=/script.php RewriteRule .* /script.php
If the existing files you wish to have handled by your script have a common set of file extensions distinct from that of the hander, you can bypass mod_rewrite and use instead mod_actions. Let's say you want all .html and .tpl files to be dealt with by your script:
Action foo-action /script.php AddHandler foo-action html tpl
RewriteCond %{QUERY_STRING} foo RewriteRule ^/url - [F]
RewriteRule ^/url /url?
Keep the existing query string using the Query String Append flag, but add var=val to the end.
RewriteRule ^/url /url?var=val [QSA]
Rewrite URLs like http://askapache.com/url1?var=val to http://askapache.com/url2?var=val but don't rewrite if val isn't present.
RewriteCond %{QUERY_STRING} val RewriteRule ^/url1 /url2
Change any single instance of val in the query string to other_val when accessing /path. Note that %1 and %2 are back-references to the matched part of the regular expression in the previous RewriteCond.
RewriteCond %{QUERY_STRING} ^(.*)val(.*)$ RewriteRule /path /path?%1other_val%2