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/

<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

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


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.

Falko Timme

About Falko Timme

Falko Timme is an experienced Linux administrator and founder of Timme Hosting, a leading nginx business hosting company in Germany. He is one of the most active authors on HowtoForge since 2005 and one of the core developers of ISPConfig since 2000. He has also contributed to the O'Reilly book "Linux System Administration".

Share this page:

Suggested articles

5 Comment(s)

Add comment


By: 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 

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


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] ModSecurity: Warning. Operator EQ match: 0. [id "960903"] [msg "ModSecurity does not support content encodings"] [severity "WARNING"] [hostname ""] [uri "/test.html"] [unique_id "Le3dBH8AAAIAAErHB-QAAAAB"]

Environment: Jetty 6.1.6, JDK 6, Spring 2.5 Web

By: 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?


aptitude install libapache2-mod-security2

By: brody182

Dont you think this needs to be updated for Debian 8?