• 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 ^(.*)$ https://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 %(.*) https://%{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 (.*) https://%{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$ https://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

Viewing 2 replies - 1 through 2 (of 2 total)
  • Thread Starter Zeb

    (@zeb-el)

    Further htaccess solution on https://www.askapache.com

    Thanks for posting this information. I am somewhat familiar with htaccess with other CMS frameworks, but know that WP has other special considerations.

    Would love someone within WP developers to give some feedback here and provide a central location to explain how to best set up the htacess files for WP.

    _CindyBarnard

Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘htaccess security issue’ is closed to new replies.