# 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]