Main Page
 The gatekeeper of reality is
 quantified imagination.

Stay notified when site changes by adding your email address:

Your Email:

Bookmark and Share
Email Notification
Project Securing Site
Purpose
The purpose of this tutorial is to show some of the ways with which you may help secure a website using the Apache htaccess file by adding some validation to it. This method may likely be the one available to most with hosted webspace (where you don't have access to other parts of Apache). Depending on what a website may be running, the rules set in this tutorial may be too strict which could result in parts of a website to not function as may be expected so be sure to experiment in a beta or non-production environment and tailor as may be needed. This particular tutorial was built on Ubuntu 12x so it is fairly new. Lastly, Spiderlabs is one of several sources for hearing about exploits.

The HTML Form
# Application Mod Rewrite Rules
RewriteEngine On

#
# The following fundamental additions have been added to improve the security of a website.
# [F] (403 Forbidden) may alternatively use, [L] (200 OK), or, [R=404,L] but usually will require additional rules to implement.
#
# [SECURITY] Deny all requests that are not defined here.
# NOTE: Other requests include PROPFIND|OPTIONS|PUT|TRACE|DELETE|TRACK|DEBUG.
RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST)$ [NC]
RewriteRule .* - [F]

# [SECURITY] If query string is invalid, prohibit the request from being processed.
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC,OR]
RewriteCond %{QUERY_STRING} \=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} [NC,OR]
RewriteCond %{QUERY_STRING} (\.\./|\.\.) [OR]
RewriteCond %{QUERY_STRING} ftp\: [NC,OR]
RewriteCond %{QUERY_STRING} http\: [NC,OR]
RewriteCond %{QUERY_STRING} https\: [NC,OR]
RewriteCond %{QUERY_STRING} \=\|w\| [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)/self/(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)cPath=http://(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*iframe.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^i]*i)+frame.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR]
RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} ^.*(\[|\]|\(|\)|<|>).* [NC,OR]
RewriteCond %{QUERY_STRING} (NULL|OUTFILE|LOAD_FILE) [OR]
RewriteCond %{QUERY_STRING} (\./|\../|\.../)+(motd|etc|bin) [NC,OR]
RewriteCond %{QUERY_STRING} (localhost|loopback|127\.0\.0\.1) [NC,OR]
RewriteCond %{QUERY_STRING} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
RewriteCond %{QUERY_STRING} concat[^\(]*\( [NC,OR]
RewriteCond %{QUERY_STRING} union([^s]*s)+elect [NC,OR]
RewriteCond %{QUERY_STRING} union([^a]*a)+ll([^s]*s)+elect [NC,OR]
RewriteCond %{QUERY_STRING} (;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|order|script|set|md5|benchmark|encode) [NC]
RewriteRule ^(.*)$ - [F]

# [SECURITY] If request header is invalid (should be something like "GET /index.html HTTP/1.1"), prohibit the request from being processed.
RewriteCond %{THE_REQUEST} etc/passwd [NC,OR]
RewriteCond %{THE_REQUEST} self/environ [NC,OR]
RewriteCond %{THE_REQUEST} cgi-bin [NC,OR]
RewriteCond %{THE_REQUEST} (%0A|%0D) [NC,OR]
RewriteCond %{THE_REQUEST} \?\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} \/\*\ HTTP/ [NC,OR]
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,OR]
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .+\ HTTP/(0\.9|1\.0|1\.1) [NC]
RewriteRule ^(.*)$ - [F]

# [SECURITY] If request uri is invalid (the URI should almost always begin with a / on Linux), prohibit the request from being processed.
# NOTE: On some systems a bogus POST request may be made where the URL is appended with a query string that targets php-cgi that would not be caught in the request rules above hence why it is included below. RewriteCond %{REQUEST_URI} !^$
RewriteCond %{REQUEST_URI} cgi-bin [NC,OR]
RewriteCond %{REQUEST_URI} !^/.*$ [NC]
RewriteRule .* - [F]

# [SECURITY] If http content disposition/type is invalid, prohibit the request from being processed.
RewriteCond %{HTTP:Content-Disposition} \.php [NC]
RewriteCond %{HTTP:Content-Type} image/.+ [NC]
RewriteRule .* - [F]

# [SECURITY] Ensure that https is used otherwise prohibit the request from being processed.
RewriteCond %{HTTPS} !=on [NC]
RewriteRule .* - [F]

# [SECURITY] If http host is invalid (in this case a beta and live site location), prohibit the request from being processed.
# If called in server-side code consider filtering it before use: preg_replace('[^a-z0-9\.-]', '', $_SERVER['HTTP_HOST'])
RewriteCond %{HTTP_HOST} !^(www.yourlivesite.com|www.yourbetasite.com) [NC]
RewriteRule .* - [F]

# [SECURITY] If server name is invalid (in this case a beta and live site location), prohibit the request from being processed.
# If called in server-side code consider filtering it before use: preg_replace('[^a-z0-9\.-]', '', $_SERVER['SERVER_NAME'])
RewriteCond %{SERVER_NAME} !^(www.yourlivesite.com|www.yourbetasite.com) [NC]
RewriteRule .* - [F]

# [SECURITY] If there's a referer but it does not match (in this case a beta and live site location), prohibit the request from being processed.
# If you don't want to restrict to one or more of your websites, you can restrict other websites - RewriteCond %{HTTP_REFERER} ^.*(google.com|wikipedia).*$ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^(https://www.yourlivesite.com|https://www.yourbetasite.com) [NC]
RewriteRule .* - [F]

# [SECURITY] If there's a request for the specified file types ensure the referer is valid (in this case a beta and live site location), otherwise prohibit the request from being processed.
RewriteCond %{HTTP_REFERER} ^$ [OR]
RewriteCond %{HTTP_REFERER} !^(https://www.yourlivesite.com|https://www.yourbetasite.com) [NC]
RewriteRule \.(css|csv|doc|docx|gif|jpg|jpeg|js|jsx|png|xls|xlsx|xml|zip)$ - [F]

# [SECURITY] If there's a post request ensure the referer is valid (in this case a beta and live site location), otherwise prohibit the request from being processed.
RewriteCond %{REQUEST_METHOD} ^(POST) [NC]
RewriteCond %{HTTP_REFERER} !^(https://www.yourlivesite.com|https://www.yourbetasite.com) [NC]
RewriteRule .* - [F]

# [SECURITY] If there's no user-agent or ones we don't want to allow (such as from pen software), prohibit the request from being processed.
RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(acunetix|arachni|anarchie|anonymous|apexoo|aqua_products|asterias|autohttp|backdoorbot|badass|blackwidow|blogchecker|blogpeople|blowfish|browsezilla|builtbottough|bullseye|clshttp|craftbot|collector|comodo|curl|cyberz|datacha0s|deepnet|digext|download|embeddedwb|extract|fetch|filehound|flamingattackbot|foobot|freshdownload|grabber|grabnet|harvest|havij|hloader|hmview|holmes|httpget|httplib|infiltrat|languard|leacher|leechftp|libwww-perl|maxpatrol|meleon|melon|metasploit|morfeus|nessus|netvampire|nikto|ninja|octopus|omniexplorer|outfoxbot|packrat|pagmiedownload|panscient|pavuk|pagegrabber|pcbrowser|perman|phpversion|plucker|programshareware|progressivedownload|propowerbotdownload|prospectordownload|prowebwalkerdownload|prozilladownload|psbot|psycheclone|pushsite|python-urllib|quepasacreep|rapid7|redcarpet|redkernel|repomonkey|rufus|scanner|sicklebot|sitesnagger|slysearch|smartdownload|snagger|snoopy|sootle|spankbot|spanner|speeddownload|spiderbot|sqlmap|sqworm|stripper|sucker|superhttp|surfbot|surfwalker|synapse|titan|urlcheck|voilabot|w3af|wbsearchbot|webaltbot|webbandit|webcapture|webcollage|webcopier|webcopy|webfetch|webmirror|webmonitor|webreaper|webpictures|webstripper|webwalk|webwhacker|widow|zeus|zmeu|zyborg).*$ [NC]
RewriteRule .* - [F]

# [SECURITY] Block specific IP addresses (use sparingly since this will add delay to response even for authorized users).
# To use an IP range instead of a specific IP address, just drop octets ex. 1\.1\.1\. will block all addresses of 1.1.1.xxx
RewriteCond %{REMOTE_ADDR} ^1\.1\.1\.1
RewriteRule ^ - [F]


About Joe