Secure Your Apache With mod_security

Version 1.0
Author: Falko Timme

This article shows how to install and configure mod_security. mod_security is an Apache module (for Apache 1 and 2) that provides intrusion detection and prevention for web applications. It aims at shielding web applications from known and unknown attacks, such as SQL injection attacks, cross-site scripting, path traversal attacks, etc.

In the first chapter I will show how to install mod_security on Debian Sarge, Ubuntu 6.06 LTS (Dapper Drake), and on Fedora Core 5, and in the second chapter I will describe how to configure Apache for mod_security which is independent from the distribution you're using.

I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!

 

1 Installation

1.1 Debian Sarge

mod_security is available as a Debian package in the default Debian repositories, therefore the installation is as simple as this:

apt-get install libapache2-mod-security
a2enmod mod-security
/etc/init.d/apache2 force-reload

 

1.2 Ubuntu 6.06 LTS (Dapper Drake)

The installation is exactly the same as on Debian Sarge:

apt-get install libapache2-mod-security
a2enmod mod-security
/etc/init.d/apache2 force-reload

 

1.3 Fedora Core 5

On Fedora, you can install and activate mod_security like this:

yum install mod_security
/etc/init.d/httpd restart

You should now find the file /etc/httpd/conf.d/mod_security.conf which already contains a basic mod_security configuration:

vi /etc/httpd/conf.d/mod_security.conf

# Example configuration file for the mod_security Apache module

LoadModule security_module modules/mod_security.so

<IfModule mod_security.c>

    # Turn the filtering engine On or Off
    SecFilterEngine On

    # The audit engine works independently and
    # can be turned On of Off on the per-server or
    # on the per-directory basis
    SecAuditEngine RelevantOnly

    # Make sure that URL encoding is valid
    SecFilterCheckURLEncoding On

    # Unicode encoding check
    SecFilterCheckUnicodeEncoding On

    # Only allow bytes from this range
    SecFilterForceByteRange 1 255

    # Cookie format checks.
    SecFilterCheckCookieFormat On

    # The name of the audit log file
    SecAuditLog logs/audit_log

    # Should mod_security inspect POST payloads
    SecFilterScanPOST On

    # Default action set
    SecFilterDefaultAction "deny,log,status:406"

    # Simple example filter
    # SecFilter 111

    # Prevent path traversal (..) attacks
    # SecFilter "\.\./"

    # Weaker XSS protection but allows common HTML tags
    # SecFilter "<( |\n)*script"

    # Prevent XSS atacks (HTML/Javascript injection)
    # SecFilter "<(.|\n)+>"

    # Very crude filters to prevent SQL injection attacks
    # SecFilter "delete[[:space:]]+from"
    # SecFilter "insert[[:space:]]+into"
    # SecFilter "select.+from"

    # Require HTTP_USER_AGENT and HTTP_HOST headers
    SecFilterSelective "HTTP_USER_AGENT|HTTP_HOST" "^$"

    # Only accept request encodings we know how to handle
    # we exclude GET requests from this because some (automated)
    # clients supply "text/html" as Content-Type
    SecFilterSelective REQUEST_METHOD "!^GET$" chain
    SecFilterSelective HTTP_Content-Type "!(^$|^application/x-www-form-urlencoded$|^multipart/form-data)"

    # Require Content-Length to be provided with
    # every POST request
    SecFilterSelective REQUEST_METHOD "^POST$" chain
    SecFilterSelective HTTP_Content-Length "^$"

    # Don't accept transfer encodings we know we don't handle
    # (and you don't need it anyway)
    SecFilterSelective HTTP_Transfer-Encoding "!^$"

    # Some common application-related rules from
    # http://modsecrules.monkeydev.org/rules.php?safety=safe

    #Nuke Bookmarks XSS
    SecFilterSelective THE_REQUEST "/modules\.php\?name=Bookmarks\&file=(del_cat\&catname|del_mark\&markname|edit_cat\&catname|edit_cat\&catcomment|marks\&catname|uploadbookmarks\&category)=(<[[:space:]]*script|(http|https|ftp)\:/)"

    #Nuke Bookmarks Marks.php SQL Injection Vulnerability
    SecFilterSelective THE_REQUEST "modules\.php\?name=Bookmarks\&file=marks\&catname=.*\&category=.*/\*\*/(union|select|delete|insert)"

    #PHPNuke general XSS attempt
    #/modules.php?name=News&file=article&sid=1&optionbox=
    SecFilterSelective THE_REQUEST "/modules\.php\?*name=<[[:space:]]*script"

    # PHPNuke SQL injection attempt
    SecFilterSelective THE_REQUEST "/modules\.php\?*name=Search*instory="

    #phpnuke sql insertion
    SecFilterSelective THE_REQUEST "/modules\.php*name=Forums.*file=viewtopic*/forum=.*\'/"

    # WEB-PHP phpbb quick-reply.php arbitrary command attempt

    SecFilterSelective THE_REQUEST "/quick-reply\.php" chain
    SecFilter "phpbb_root_path="

    #Topic Calendar Mod for phpBB Cross-Site Scripting Attack
    SecFilterSelective THE_REQUEST "/calendar_scheduler\.php\?start=(<[[:space:]]*script|(http|https|ftp)\:/)"

    # phpMyAdmin: Safe

    #phpMyAdmin Export.PHP File Disclosure Vulnerability
    SecFilterSelective SCRIPT_FILENAME "export\.php$" chain
    SecFilterSelective ARG_what "\.\."

    #phpMyAdmin path vln
    SecFilterSelective REQUEST_URI "/css/phpmyadmin\.css\.php\?GLOBALS\[cfg\]\[ThemePath\]=/etc"

</IfModule>

You can keep this configuration, but to get a better understanding of what mod_security can do, you should comment out the <IfModule mod_security.c>...</IfModule> part, restart Apache, and follow chapter 2. Afterwards you can create your own mod_security ruleset, or just switch back to this one.

Share this page:

4 Comment(s)

Add comment

Comments

From: Anonymous

jnordstrom I noticed this exact same thing in my logs you can either. change deflate.conf to look like this and the error will still be there only for some hosts.

<IFMODULE mod_deflate.c>
# Commented out filter below to disable default compression to allow some 
# virtual hosts to have no compression. 
# AddOutputFilterByType DEFLATE text/html text/plain text/xml 
</IFMODULE>

Another alternative is to just edit the rule file and ditch the warning. I'm busy contemplating which one to do myself right now.

From:

Given your experience with both mod_security and mod_deflate I was wondering if you had experienced the same conflicts that I have. When I disable mod_deflate, mod_security works great, when I enable mod_deflate I get:

[Mon Dec 10 16:21:28 2007] [error] [client 127.0.0.1] ModSecurity: Warning. Operator EQ match: 0. [id "960903"] [msg "ModSecurity does not support content encodings"] [severity "WARNING"] [hostname "www.testsite.com"] [uri "/test.html"] [unique_id "Le3dBH8AAAIAAErHB-QAAAAB"]


Environment: Jetty 6.1.6, JDK 6, Spring 2.5 Web

From: Phil

Just wondering if there was a set of rules, like there is for phpids that are constantly updated? or do you have to keep designing your own rules?

From:

aptitude install libapache2-mod-security2