The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. December 05, 2008, 02:13:36 AM

Login with username, password and session length


Pages: [1]
  Print  
Author Topic: Great example of Web Firewall via .htaccess or httpd.conf  (Read 355 times)
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 5229


:sniffle: Humor was so much easier before.


View Profile
« on: July 24, 2008, 08:26:24 AM »

A friend just posted this in another location and I think it's an excellent notion: It's essentially a mod_rewrite that will help block typical attacks against a website BEFORE the request gets to your PHP (or whatever) code. I like it because it's DAMN broad (in fact, too broad for my liking in the UserAgent arena, as perhaps you'll see) and using this code on a cheap host would shift the processor burden of protecting your sites to the Apache daemon instead of (you).

Find it here: www dot 0x000000 dot com/index.php?i=558

Enjoy!
Logged

If I can't be Mr. Root then I don't want to play.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 5229


:sniffle: Humor was so much easier before.


View Profile
« Reply #1 on: July 24, 2008, 08:53:46 AM »

For those of you that have the ability, I just played with this stuff in a primary <Directory> directive in httpd.conf and it worked like a charm. In other words, you could use this in httpd.conf as a "root level" firewall protecting all virtual hosts. This would be MOST effective in a situation where your apache instance is also behind a physical firewall doing port forwarding to 80 and 443 only - because if there is no physical access to anything on the box except Apache and httpd.conf has Apache pretty locked down, you're in really good shape. Bear in mind that this does almost nothing against MySQL injection attacks.

For those without httpd.conf access, this will still work nicely in a .htaccess file.

Just in case it is ever taken down, here it is for posterity:

RewriteEngine On
Options +FollowSymLinks
ServerSignature Off

RewriteCond %{REQUEST_METHOD}  ^(HEAD|TRACE|DELETE|TRACK) [NC,OR]
RewriteCond %{THE_REQUEST}     ^.*(\\r|\\n|%0A|%0D).* [NC,OR]

RewriteCond %{HTTP_REFERER}    ^(.*)(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{HTTP_COOKIE}     ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{REQUEST_URI}     ^/(,|;|:|<|>|">|"<|/|\\\.\.\\).{0,9999}.* [NC,OR]

RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|scan).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]

RewriteCond %{QUERY_STRING}    ^.*(;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|cast|set|declare|drop|update|md5|benchmark).* [NC,OR]
RewriteCond %{QUERY_STRING}    ^.*(localhost|loopback|127\.0\.0\.1).* [NC,OR]
RewriteCond %{QUERY_STRING}    ^.*\.[A-Za-z0-9].* [NC,OR]
RewriteCond %{QUERY_STRING}    ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC]

RewriteRule ^(.*)$ access_log.php


Thanks MUCH to the anonymous hacker that posted it there.
« Last Edit: July 24, 2008, 08:55:20 AM by perkiset » Logged

If I can't be Mr. Root then I don't want to play.
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 3453


View Profile
« Reply #2 on: July 24, 2008, 09:42:05 AM »

er, where do I put this?

in the <directory "/some/path/here"> node?
or in the blank directory node? Im guessing the one with a path, since we only want those rules applied to the actual web directories?
Logged
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 3453


View Profile
« Reply #3 on: July 24, 2008, 09:51:22 AM »

I didnt know what serversignature off did, so i looked it up, it hides your version number on error pages.
apparently it is also a good idea to add "ServerTokens Prod" which returns only the product only server:apache
edit: nevermind, apparently tokens cannot be used in httpd.conf
« Last Edit: July 24, 2008, 05:18:17 PM by nutballs » Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 5229


:sniffle: Humor was so much easier before.


View Profile
« Reply #4 on: July 24, 2008, 10:56:06 AM »

Hang tough, I'm working through some efficiency things. The original poster was thorough, but it is not efficient enough for what I'd like.

More in a bit. I'm gonna tweak the sequence and put it up on a production box and watch for a bit.
Logged

If I can't be Mr. Root then I don't want to play.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 5229


:sniffle: Humor was so much easier before.


View Profile
« Reply #5 on: July 24, 2008, 11:47:09 AM »

OK I like this better:

        RewriteEngine On
        ServerSignature Off

        RewriteCond     %{QUERY_STRING} ^$
        RewriteCond     %{REQUEST_METHOD}       ^GET$   [NC]
        RewriteCond     %{REQUEST_URI}  ^[a-z0-9\-_\.\/]+\.(jpg|gif|png|jpeg|html|htm|php)$ [NC]
        RewriteRule     ^(.*)$  -       [L]

        RewriteCond     %{REQUEST_METHOD}  ^(HEAD|TRACE|DELETE|TRACK) [NC,OR]
        RewriteCond     %{THE_REQUEST}     ^.*(\\r|\\n|%0A|%0D).* [NC,OR]
        RewriteCond     %{HTTP_REFERER}    ^(.*)(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
        RewriteCond     %{HTTP_COOKIE}     ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
        RewriteCond     %{REQUEST_URI}     ^/(,|;|:|<|>|">|"<|/|\\\.\.\\).{0,9999}.* [NC,OR]
        RewriteCond     %{HTTP_USER_AGENT} ^$ [OR]
        RewriteCond     %{HTTP_USER_AGENT} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
        RewriteCond     %{QUERY_STRING}    ^.*(;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|cast|set|declare|drop|update|md5|benchmark).* [NC,OR]
        RewriteCond     %{QUERY_STRING}    ^.*(localhost|loopback|127\.0\.0\.1).* [NC,OR]
        RewriteCond     %{QUERY_STRING}    ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC]

        RewriteRule (.*)         http://www.godaddy.com/?


Three things have changed since the first version: I ditched the line

RewriteCond %{QUERY_STRING}    ^.*\.[A-Za-z0-9].* [NC,OR]


... because I have no idea where he was going: a query string with any amount of any character, followed by a period, followed by A-Z0-9 followed by any character... completely lost me on what kind of restriction that is.

The ditched the UA restrictions because I think that killing a surfer because it's robotic would be the responsibility of the site master rather that at the server level. There are many times I'm plenty happy if a bot is working me.

Lastly, I moved to an optimistic "header" in the sequence, that asks:

   If the query string is blank (and)
   the request method is cleanly GET (and)
   the url contains nothing except A-Z0-9-_/. and is tailed by "." and then either jpg/gif/png etc at the end


... then I call it a vanilla URL and stop processing. Why? Because the VAST majority of the time I will have simple requests from normal surfers and rather than imposing all of the RewriteConds on every single request (bear in mind, this is for EVERY file, including graphics) I'll pass the vast majority of requests. This will help in throughput of the vFirewall. This means that all calls for a PDF, flash, POSTS etc will still run through the entire process. Interested in any comments you might have here.

Lastly, rather than keeping the surfer here, I've bounced them to a blackhole site. The problem I found was that in the httpd.conf <Directory> area I can't seem to bounce them to a static file on my box... so instead I redirect away. I could redirect them right back to my own box and a black hole file, but then I'm taking two hits for one bonehead call...

Thoughts?
« Last Edit: July 24, 2008, 11:51:26 AM by perkiset » Logged

If I can't be Mr. Root then I don't want to play.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 5229


:sniffle: Humor was so much easier before.


View Profile
« Reply #6 on: July 24, 2008, 11:50:09 AM »

er, where do I put this?

in the <directory "/some/path/here"> node?
or in the blank directory node? Im guessing the one with a path, since we only want those rules applied to the actual web directories?

In the one where you define access, not the one where you deny access. In most configs this will be the second <Directory> block.
Logged

If I can't be Mr. Root then I don't want to play.
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 3453


View Profile
« Reply #7 on: July 24, 2008, 12:04:42 PM »

thats what I figured on where to put it.

Yea, I was trying to decifer the restrictions as well, and frankly, I dont care if someone is scraping my site, it usually results in backlinks because people dont usually know what they are doing, or dont care either. SO would probably keep the agent stuff there, but set an agent that doesnt actually exist, for "just in case I ever want to".

a couple of the lines Im not really sure i understood either.
the only restrictions that can be a problem are the html removals, but those are probably a rare problem. But I generally would prefer to make my code safe, not rely on an external force like the conf to secure me against XSS or injections.
I can see this as making me a bit lazy...
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 5229


:sniffle: Humor was so much easier before.


View Profile
« Reply #8 on: July 24, 2008, 12:06:55 PM »

I worry not for XSS because what the engines see is not what a bonehead would be injecting Wink

(worked through that one when JasonD came a'calling against one of my sites once)
Logged

If I can't be Mr. Root then I don't want to play.
Pages: [1]
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!