I have searched and wasted a lot of precious time to find out about how to configure the .htaccess. However, there is not so much information in this regard here on this website in ONE place. This issue should be a central matter for security reasons.
Finally, after lot of searches, I found the following articles published i several sites. Accordingly, I am very curious if these configurations and hacks are accurate and actually work properly with WP 3.2.1 though they are about 1-2 years old!
Even if there is some issues that might need modifications with your help, I believe it is important for all of us WordPress users to consider taking security issues and htaccess even more seriously.
I appreciate if any one of you that is specialist in wordpress could take a look at it. This issue could solve a lot of problems people have regarding the .htaccess issue.
Thank you in advance.
# BEGIN WordPress
RewriteEngine On
Options -Indexes
# Add www (change www.example.com to example.com to remove www)
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [PT]
# Keep bots away from commenting
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
RewriteCond %{HTTP_REFERER} POST
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteCond %(.*) http://%{REMOTE_ADDR} /$ [R=301,L]
# Disable ETags
Header unset ETag
FileETag None
# Suppress PHP errors
php_flag display_startup_errors off
php_flag display_errors off
php_flag html_errors off
php_value docref_root 0
php_value docref_ext 0
ExpiresActive On
ExpiresDefault A0
<FilesMatch ".(gif|jpg|jpeg|png|swf)$">
# 2 weeks
ExpiresDefault A1209600
Header append Cache-Control "public"
</FilesMatch>
<FilesMatch ".(xml|txt|html)$">
# 2 hours
ExpiresDefault A7200
Header append Cache-Control "proxy-revalidate"
</FilesMatch>
<FilesMatch ".(js|css)$">
# 3 days
ExpiresDefault A259200
Header append Cache-Control "proxy-revalidate"
</FilesMatch>
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
<Files wp-config.php>
Order Deny,Allow
Deny from all
</Files>
RewriteRule ^(.*/)?.svn/ - [F,L]
gzip handler
<FilesMatch ".js$">
AddHandler application/x-httpd-php .js
php_value default_mimetype "text/javascript"
</FilesMatch>
<FilesMatch ".css$">
AddHandler application/x-httpd-php .css
php_value default_mimetype "text/css"
</FilesMatch>
<FilesMatch ".(htm|html|shtml)$">
AddHandler application/x-httpd-php .html
php_value default_mimetype "text/html"
</FilesMatch>
php_value auto_prepend_file /absolute/path/to/gzip.php
Deny spambots from comments
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
RewriteCond %{HTTP_REFERER} !.*yourdomain.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) http://%{REMOTE_ADDR}/$ [R=301,L]
Redirect empty searches to root
# Redirect Empty Searches to root
RewriteCond %{QUERY_STRING} ^s=$
RewriteRule ^ /? [L,R=301]
htaccess for a better login URL
RewriteRule ^login$ http://website.com/wp-login.php [NC,L]
Block common exploit
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]
Admin IP whitelist
AuthUserFile /dev/null
AuthGroupFile /dev/null
AuthName "WordPress Admin Access Control"
AuthType Basic
<LIMIT GET>
order deny,allow
deny from all
# whitelist Admin's IP address
allow from xx.xx.xx.xxx
# whitelist User 1's IP address
allow from xx.xx.xx.xxx
# whitelist User 2's IP address
allow from xx.xx.xx.xxx
</LIMIT>
ExecCG specifies NO files that are registered to be handled by cgi-script handler are allowed. (This command did not work in my installation and generated server failure)
Options -ExecCGI
AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
PartII, 4G Black list (This part seems not to work with WordPress. Please try the original hack from Presenting the Perishable Press 4G Blacklist.)
### PERISHABLE PRESS 4G BLACKLIST ###
# ESSENTIALS
RewriteEngine on
ServerSignature Off
Options All -Indexes
Options +FollowSymLinks
# FILTER REQUEST METHODS
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_METHOD} ^(TRACE|DELETE|TRACK) [NC]
RewriteRule ^(.*)$ - [F,L]
</IfModule>
# BLACKLIST CANDIDATES
<Limit GET POST PUT>
Order Allow,Deny
Allow from all
Deny from 75.126.85.215 "# blacklist candidate 2008-01-02 = admin-ajax.php attack "
Deny from 128.111.48.138 "# blacklist candidate 2008-02-10 = cryptic character strings "
Deny from 87.248.163.54 "# blacklist candidate 2008-03-09 = block administrative attacks "
Deny from 84.122.143.99 "# blacklist candidate 2008-04-27 = block clam store loser "
Deny from 210.210.119.145 "# blacklist candidate 2008-05-31 = block _vpi.xml attacks "
Deny from 66.74.199.125 "# blacklist candidate 2008-10-19 = block mindless spider running "
Deny from 203.55.231.100 "# 1048 attacks in 60 minutes"
Deny from 24.19.202.10 "# 1629 attacks in 90 minutes"
</Limit>
# QUERY STRING EXPLOITS
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ../ [NC,OR]
RewriteCond %{QUERY_STRING} boot.ini [NC,OR]
RewriteCond %{QUERY_STRING} tag= [NC,OR]
RewriteCond %{QUERY_STRING} ftp: [NC,OR]
RewriteCond %{QUERY_STRING} http: [NC,OR]
RewriteCond %{QUERY_STRING} https: [NC,OR]
RewriteCond %{QUERY_STRING} mosConfig [NC,OR]
# RewriteCond %{QUERY_STRING} ^.*([|]|(|)|<|>|'|"|;|?|*).* [NC,OR]
# RewriteCond %{QUERY_STRING} ^.*(%22|%27|%3C|%3E|%5C|%7B|%7C).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(%0|%A|%B|%C|%D|%E|%F|127.0).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(globals|encode|localhost|loopback).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(request|select|insert|union|declare|drop).* [NC]
RewriteRule ^(.*)$ - [F,L]
</IfModule>
# CHARACTER STRINGS
<IfModule mod_alias.c>
# BASIC CHARACTERS
RedirectMatch 403 ,
RedirectMatch 403 :
RedirectMatch 403 ;
# RedirectMatch 403 =
RedirectMatch 403 @
RedirectMatch 403 [
RedirectMatch 403 ]
RedirectMatch 403 ^
RedirectMatch 403 '
RedirectMatch 403 {
RedirectMatch 403 }
RedirectMatch 403 ~
RedirectMatch 403 "
RedirectMatch 403 $
RedirectMatch 403 <
RedirectMatch 403 >
RedirectMatch 403 |
RedirectMatch 403 ..
# RedirectMatch 403 //
RedirectMatch 403 %0
RedirectMatch 403 %A
RedirectMatch 403 %B
RedirectMatch 403 %C
RedirectMatch 403 %D
RedirectMatch 403 %E
RedirectMatch 403 %F
RedirectMatch 403 %22
RedirectMatch 403 %27
RedirectMatch 403 %28
RedirectMatch 403 %29
RedirectMatch 403 %3C
RedirectMatch 403 %3E
# RedirectMatch 403 %3F
RedirectMatch 403 %5B
RedirectMatch 403 %5C
RedirectMatch 403 %5D
RedirectMatch 403 %7B
RedirectMatch 403 %7C
RedirectMatch 403 %7D
# COMMON PATTERNS
Redirectmatch 403 _vpi
RedirectMatch 403 .inc
Redirectmatch 403 xAou6
Redirectmatch 403 db_name
Redirectmatch 403 select(
Redirectmatch 403 convert(
Redirectmatch 403 /query/
RedirectMatch 403 ImpEvData
Redirectmatch 403 .XMLHTTP
Redirectmatch 403 proxydeny
RedirectMatch 403 function.
Redirectmatch 403 remoteFile
Redirectmatch 403 servername
Redirectmatch 403 &rptmode=
Redirectmatch 403 sys_cpanel
RedirectMatch 403 db_connect
RedirectMatch 403 doeditconfig
RedirectMatch 403 check_proxy
Redirectmatch 403 system_user
Redirectmatch 403 /(null)/
Redirectmatch 403 clientrequest
Redirectmatch 403 option_value
RedirectMatch 403 ref.outcontrol
# SPECIFIC EXPLOITS
RedirectMatch 403 errors.
# RedirectMatch 403 config.
RedirectMatch 403 include.
RedirectMatch 403 display.
RedirectMatch 403 register.
Redirectmatch 403 password.
RedirectMatch 403 maincore.
RedirectMatch 403 authorize.
Redirectmatch 403 macromates.
RedirectMatch 403 head_auth.
RedirectMatch 403 submit_links.
RedirectMatch 403 change_action.
Redirectmatch 403 com_facileforms/
RedirectMatch 403 admin_db_utilities.
RedirectMatch 403 admin.webring.docs.
Redirectmatch 403 Table/Latest/index.
</IfModule>
Sources:
1. 20 Steps to a Flexible and Secure WordPress Installation
2. The Ultimate Guide to .htaccess Files
3. Presenting the Perishable Press 4G Blacklist.
4. WORDPRESS CODE SNIPPETS