Latest TweetsPlugin update! Disable Gutenberg v1.5 adds whitelist options to always enable Block Editor on any post :) m0n.co/wpdg
Perishable Press

5G Blacklist 2013

[ 5G (2013) ] Following up on much feedback (and this post), here is an update for the 5G Blacklist for 2013. As explained in the 2012 article (and elsewhere), the 5G Blacklist helps reduce the number of malicious URL requests that hit your website. It’s one of many ways to improve the security of your site and protect against evil exploits, bad requests, and other nefarious garbage. If your site runs on Apache and you’re familiar with .htaccess, the 5G is an effective way to secure your site against malicious HTTP requests and other suspect activity.

Update: Check out the new and improved 6G Firewall »

About the 5G Blacklist

The 5G Blacklist is a simple, flexible blacklist that checks all URI requests against a series of carefully constructed HTAccess directives. This happens quietly behind the scenes at the server level, saving resources for stuff like PHP and MySQL for all blocked requests.

How it works

Blacklists can block just about any part of a request: IP, user agent, request string, query string, referrer, and everything in between. But IP addresses change constantly, and user agents and referrers are easily spoofed. As discussed, request strings yield the best results: greater protection with fewer false positives.

The 5G works beautifully with WordPress, and should help any site conserve bandwidth and server resources while protecting against malicious activity.

5G Blacklist 2013

Here is the third version of the 5th generation blacklist:

# 5G BLACKLIST/FIREWALL (2013)
# @ https://perishablepress.com/5g-blacklist-2013/

# 5G:[QUERY STRINGS]
<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteBase /
	RewriteCond %{QUERY_STRING} (\"|%22).*(<|>|%3) [NC,OR]
	RewriteCond %{QUERY_STRING} (javascript:).*(\;) [NC,OR]
	RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3) [NC,OR]
	RewriteCond %{QUERY_STRING} (\\|\.\./|`|=\'$|=%27$) [NC,OR]
	RewriteCond %{QUERY_STRING} (\;|\'|\"|%22).*(union|select|insert|drop|update|md5|benchmark|or|and|if) [NC,OR]
	RewriteCond %{QUERY_STRING} (base64_encode|localhost|mosconfig) [NC,OR]
	RewriteCond %{QUERY_STRING} (boot\.ini|echo.*kae|etc/passwd) [NC,OR]
	RewriteCond %{QUERY_STRING} (GLOBALS|REQUEST)(=|\[|%) [NC]
	RewriteRule .* - [F]
</IfModule>

# 5G:[USER AGENTS]
<IfModule mod_setenvif.c>
	# SetEnvIfNoCase User-Agent ^$ keep_out
	SetEnvIfNoCase User-Agent (binlar|casper|cmsworldmap|comodo|diavol|dotbot|feedfinder|flicky|ia_archiver|kmccrew|nutch|planetwork|purebot|pycurl|skygrid|sucker|turnit|vikspider|zmeu) keep_out
	<limit GET POST PUT>
		Order Allow,Deny
		Allow from all
		Deny from env=keep_out
	</limit>
</IfModule>

# 5G:[REQUEST STRINGS]
<IfModule mod_alias.c>
	RedirectMatch 403 (https?|ftp|php)\://
	RedirectMatch 403 /(https?|ima|ucp)/
	RedirectMatch 403 /(Permanent|Better)$
	RedirectMatch 403 (\=\\\'|\=\\%27|/\\\'/?|\)\.css\()$
	RedirectMatch 403 (\,|\)\+|/\,/|\{0\}|\(/\(|\.\.\.|\+\+\+|\||\\\"\\\")
	RedirectMatch 403 \.(cgi|asp|aspx|cfg|dll|exe|jsp|mdb|sql|ini|rar)$
	RedirectMatch 403 /(contac|fpw|install|pingserver|register)\.php$
	RedirectMatch 403 (base64|crossdomain|localhost|wwwroot|e107\_)
	RedirectMatch 403 (eval\(|\_vti\_|\(null\)|echo.*kae|config\.xml)
	RedirectMatch 403 \.well\-known/host\-meta
	RedirectMatch 403 /function\.array\-rand
	RedirectMatch 403 \)\;\$\(this\)\.html\(
	RedirectMatch 403 proc/self/environ
	RedirectMatch 403 msnbot\.htm\)\.\_
	RedirectMatch 403 /ref\.outcontrol
	RedirectMatch 403 com\_cropimage
	RedirectMatch 403 indonesia\.htm
	RedirectMatch 403 \{\$itemURL\}
	RedirectMatch 403 function\(\)
	RedirectMatch 403 labels\.rdf
	RedirectMatch 403 /playing.php
	RedirectMatch 403 muieblackcat
</IfModule>

# 5G:[REQUEST METHOD]
<ifModule mod_rewrite.c>
	RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
	RewriteRule .* - [F]
</IfModule>

# 5G:[BAD IPS]
<limit GET POST PUT>
	Order Allow,Deny
	Allow from all
	# uncomment/edit/repeat next line to block IPs
	# Deny from 123.456.789
</limit>

To use: include the entire 5G Blacklist in the root .htaccess file of your site. Remember to backup your original .htaccess file before making any changes. Test thoroughly while enjoying your favorite beverage. If you encounter any issues, please read the troubleshooting tips and/or leave a comment to report a bug.

Note: in some cases it may be necessary to place the QUERY STRING rules before WP-permalink rules.

Update (2015/04/03): removed jakarta from the user-agent portion of the list. Reason? LinkedIn actually includes the term “jakarta” in their user-agent string:

LinkedInBot/1.0 (compatible; Mozilla/5.0; Jakarta Commons-HttpClient/3.1 +http://www.linkedin.com)

</update>

Pre-changelog notes

The changes made for 5G 2013 are aimed at maximizing compatibility. Unfortunately, a number of required changes are due to improper coding and ignoring HTTP specifications. As mentioned previously, using unsafe characters in URLs obsoletes security measures that are based on pattern-matching, which is integral to the process of blocking malicious activity.

To illustrate, it is possible to protect against a wide range of malicious requests by blocking unsafe characters such as unencoded question marks “?” included within the query string. Firewalls, blacklists, security plugins and scripts are able to safely block such bad requests UNTIL some widely used service such as Google Adwords decides to start including multiple unencoded question marks in their query strings. Suddenly blocking potentially dangerous “?” requests is useless because nobody wants to block legitimate (Google) traffic.

Moral of the story: if you develop for the Web, contribute to its security by encoding your URLs according to spec. If you use security plugins, firewalls/blackists, and scripts that rely on pattern-matching to protect your site, please encourage and educate others about the importance of adhering to HTTP specifications.</rant>

Changelog

Removed from QUERY STRINGS

  • Square brackets “[” and “]” (details)
  • Colon “:” (details)
  • Unencoded question mark “\?” (WP previews, Piwik, Adwords, et al)
  • Removed “(menu|mod|path|tag)\=\.?/?” (WP menus, WP Super Cache, Joomla, Googlebot, et al)
  • Removed “environ” (common string)
  • Removed “scanner” (various WP plugins)
  • Removed “%3E” (common string)
  • Escaped backslash, from “\” to “\\

Removed from USER AGENTS

  • Commented out match for blank/empty user-agent “^$” (PayPal, WP-Piwik, et al)
  • Removed match for “libwww” (used by Lynx browser)

Removed from REQUEST STRINGS

  • Double forward slash “//” (Pingdom, gtmetrix, et al)
  • Removed match for “/cgi/” (Fancy indexes, Authentication)

Added to QUERY STRINGS (5G 2013)

  • TRACE” and “TRACK
  • base64_encode.*\(
  • \|%3E
  • GLOBALS(=|\[|\%)
  • REQUEST(=|\[|\%)
  • `
  • (\"|%22).*(<|>|%3)
  • (<|%3C).*script.*(>|%3)
  • (javascript:).*(\;)
  • (\;|\'|\"|%22).*(union|select|insert|drop|update|md5|benchmark|or|and|if)

Other changes

Optimized syntax, improved formatting.

Troubleshooting

If there is an error, remove the code and make a backup of your original .htaccess file (if you haven’t already done so). Investigate the URL for whichever page is blocked or not working, making note of any non-alphanumeric characters or anything else that looks unusual. With a good idea of what to look for, examine the 5G directives to see if anything looks similar. If so, try removing (or commenting out) the offending line (or characters) and see if that resolves the issue.

If that doesn’t work, further investigation is required, and there are numerous ways of going about it. Here is a good walkthrough of my halving method of isolating problematic code, which I recommend unless you have your own favorite way of troubleshooting ;)

Show support

If you benefit from my work with the 5G and would like to show support, consider buying a copy of my book, .htaccess made easy. You’ll get a complete guide to .htaccess, exclusive forum access, and a ton of awesome techniques for configuring, optimizing, and securing your site. Your generous support allows me to continue developing 5G/6G and other awesome resources for the community. Thank you!

Disclaimer

The 5G Firewall is provided “as-is”, with the intention of helping site administrators protect their sites against bad requests and other malicious activity. The code is open and free to use and modify as long as the first two credit lines remain intact. By using this code you assume all risk & responsibility for anything that happens, whether good or bad. In short, use wisely, test thoroughly, don’t sue me.

Learn more..

To learn more about the theory and development of the 5G Firewall, check out my articles on building the 3G, 4G and 5G Blacklist. The 6G beta article also contains some good information. And if all that’s not enough, a quick search for “blacklist” in the sidebar should also yield many results.

Jeff Starr
About the Author Jeff Starr = Web Developer. Security Specialist. WordPress Buff.
Archives
91 responses
  1. Thanks for all your hard work, I have immediately replaced my old 5G with this one.

  2. Great to see an update – thanks for putting it together.

    So is this to be used instead of the 6G beta? And no case-Insensitive RedirectMatch (?i) you used in the 6G beta? (not criticizing, just interested).

    Cheers
    I

    • Jeff Starr

      I just haven’t had time to work much more on the 6G, which remains on the horizon until later. There are a couple of tricks that will be used in 6G that aren’t used in 5G (as you mention), such as the case-insensitive RedirectMatch and positive/negative lookaheads (which are very cool).

  3. Up and running on my site. Thanks so much, Jeff!

  4. I added two evil agent ZmEu and w00tw00t to the list

    # SetEnvIfNoCase User-Agent ^$ keep_out
    SetEnvIfNoCase User-Agent

  5. Hi! =)
    Again: Comodo is a right and safe company that make it’s personalized broswser from Firefox and Chromium.
    More info: http://www.comodo.com/home/browsers-toolbars/internet-products.php
    So, comodo match string is wrong.

  6. Will the BBQ WordPress plugin adopt the updates, too?

  7. Hi,

    For confirmation: If a wp site uses the BBQ plugin, is this code not required or it’s better if its implemented as well?

    Thanks for sharing this awesome work!

    • Jeff Starr

      There is a lot of overlap between BBQ and 5G, but they’re not identical. Personally I use 5G because the performance is a little better handling HTTP requests at the server level, but either one will help protect your site, and it’s fine to use both!

  8. Works great with joomla sites.

    At one stage, got internal 500 error, but that was because of a line break, that notepad must have put in …
    the line under SetEnvIfNoCase User-Agent … as it was too long.
    removed the line break when i pasted it into htaccess file, and all is well.
    Thanks again Jeff

  9. Do you still recommend using the 5G WordPress Add-on, or is that not needed any more?

  10. I’m new at this, but I really appreciate your hard work and the fact that you make this available. I just replaced the old 5G with this and I have a question for you. Does this include the Blacklist Candidate 2012-11-13: Evil Scanner Edition (mini firewall 2012-11-13) code or should I leave it in place in my .htaccess file? So far I’ve left it in place because I don’t see anything similar in the new 5G code, but, like I said, I am new at this. Thanks in advance!

  11. Definately the best version yet! I’ve found the THE_REQUEST variable especially effective for this more advanced anti-exploit code.

    This is definately a one of a kind resource, you would be nuts not to use this. Can’t wait for the next versions!

  12. Thank you for your excellent work!!

    Here’s some more for you to look at. Came across some new hacks being tried on our WordPress sites. Here’s some of the things I’m seeing in the url (seen 1/20/13)… (recorded by the “Better WP Security” WordPress plugin)

    /wp-includes/js/jquery/&&(t=e.type)===
    /wp-includes/js/jquery/&&n.unshift(
    /wp-includes/js/jquery/).cloneNode(!0).outerHTML!==
    /wp-includes/js/jquery/+M.replace(
    /wp-includes/js/jquery/+f.split(
    /wp-includes/js/jquery/&&(i.detachEvent(
    /wp-includes/js/jquery/)?n.form:t;r&&!v._data(r,
    /wp-includes/js/jquery/).split(
    /wp-includes/js/jquery/).length&&i.push(
    /wp-includes/js/jquery/))?c=l.replace(n,
    /wp-includes/js/jquery/).length?!1:(e.lastChild.className=
    /wp-includes/js/jquery/&&(n.style.display=
    /wp-includes/js/jquery/&&((n=e.getAttribute(
    /wp-includes/js/jquery/&&t.type!==
    /wp-includes/js/jquery/).sort().join(
    /wp-includes/js/jquery/);p.setAttribute(
    /wp-includes/js/jquery/)).split(
    /wp-includes/js/jquery/.split(
    /wp-includes/js/jquery/);t.remove();if(n===
    /wp-includes/js/jquery/).off(
    /wp-includes/js/jquery/&&e.charAt(e.length-1)===
    /wp-includes/js/jquery/&&(r.innerHTML=
    /wp-includes/js/jquery/).length)&&v.error(
    /wp-includes/js/jquery/);i.className=e?v.trim(r):
    /wp-includes/js/jquery/+t))();v.error(
    /wp-includes/js/jquery/+i.className+
    /wp-includes/js/jquery/+b.join(
    /wp-includes/js/jquery/+Math.random()).replace(
    /wp-includes/js/jquery/&&e.type===

    All my code is in the httpd.conf file (instead of .htaccess) to benefit the entire server (we have lots of domains). I hear putting the code in the .conf file supposedly helps lower the workload of the server a bit, too.

    I know enough of this stuff to get around and break it kinda thing, but I’m no expert. Server logs had a few:

    “Directory index forbidden by Options directive: /httpdocs/wp-includes/js/jquery/”

    …for the time & ip, but not as many as recorded by the plugin.

    Some of what I have helps blocks several common hacks to secure the wp-includes folder, like:

    RewriteRule ^wp-admin/includes/ - [F,L]
    RewriteRule !^wp-includes/ - [S=2]
    RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
    RewriteRule ^wp-includes/theme-compat/ - [F,L]

    …and then I just added:

    RedirectMatch 403 \!\=\=
    RedirectMatch 403 \=\=\=
    RedirectMatch 403 jquery\/\&\&

    Hopefully this offers some value you can use it to make your blacklist even better!

    Thank you again!
    -Mike

[ Comments are closed for this post ]