Implement Free WAF With ModSecurity and Owasp Core rule set (CRS) v3

Installing web application firewall (WAR) is very important to protect production server website against cyber attack, but some of the mid to low range companies have a budget constraint, because many WAF products are expensive, so I will share to you how to implement WAF freely with Mod Security and OWASP CRS and we are gonna use Centos as Operationg System.


First you must enable EPEL repository.

For centOS 7 Run this command:

rpm -Uvh

For centOS 6:

rpm -Uvh


Then you must install mod_security apache module with predefined rules.

Run this command :

yum install mod_security mod_security_crs

Then You should edit the mod_Security configuration file at /etc/httpd/conf.d/mod_security.conf ,  look for the SecRuleEngine :

  1. On – Rules are activated
  2. Off – Rules are Deactivated
  3. DetectionOnly – Only Intercepts and logs Transactions

Since we want to Intercept and Block Attacks we configure it with On.

SecRuleEngine on

After this, restart Apache service :

service httpd restart

To ensure that our web application firewall is working you should see something like this in Apache error logs.

tail /var/log/httpd/error_log
[Wed Aug 15 10:35:14.915226 2018] [:notice] [pid 27094] ModSecurity: APR compile                                                                                                                     d version="1.4.8"; loaded version="1.4.8"
 [Wed Aug 15 10:35:14.915232 2018] [:notice] [pid 27094] ModSecurity: PCRE compil                                                                                                                     ed version="8.32 "; loaded version="8.32 2012-11-30"
 [Wed Aug 15 10:35:14.915236 2018] [:notice] [pid 27094] ModSecurity: LUA compile                                                                                                                     d version="Lua 5.1"
 [Wed Aug 15 10:35:14.915239 2018] [:notice] [pid 27094] ModSecurity: LIBXML comp                                                                                                                     iled version="2.9.1"

Sometimes you found that secstatusengine disabled by default.

[Wed Aug 15 10:35:14.915242 2018] [:notice] [pid 27094] ModSecurity: Status engine is currently disabled, enable it by set SecStatusEngine to On.

To solve this issue add this line on your /etc/httpd/conf.d/mod_security.conf

SecStatusEngine on

Then restart your apache service

service httpd restart

Run this command again to ensure all the configuration are working :

tail /var/log/httpd/error_log
[Wed Aug 15 10:38:35.479348 2018] [:notice] [pid 27622] ModSecurity: PCRE compiled version="8.32 "; loaded version="8.32 2012-11-30"
 [Wed Aug 15 10:38:35.479351 2018] [:notice] [pid 27622] ModSecurity: LUA compiled version="Lua 5.1"
 [Wed Aug 15 10:38:35.479353 2018] [:notice] [pid 27622] ModSecurity: LIBXML compiled version="2.9.1"
 [Wed Aug 15 10:38:35.479390 2018] [:notice] [pid 27622] ModSecurity: StatusEngine call: "2.9.2,Apache/2.4.6 (CentOS),1.4.8/1.4.8,8.32/8.32 2012-11-30,Lua 5.1,2.9.1,56"
 [Wed Aug 15 10:38:36.202229 2018] [:notice] [pid 27622] ModSecurity: StatusEngine call successfully sent. For more information visit:

They are some important files to remember in mod security

  • Mod Security Config File – /etc/httpd/conf.d/mod_security.conf
  • Debug Log – /var/log/httpd/modsec_debug.log
  • Audit log – /var/log/httpd/modsec_audit.log
  • Rules – /etc/httpd/modsecurity.d/activated_rules

In this step you already successfully install WAF using Mod Security, next step we also need to install Owasp Core rule set (CRS)

Installing Owasp Core rule set (CRS) v3

The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack detection rules for use with ModSecurity. We can say this is the core engine of WAF, because it provides protection against many common attack categories, including SQL Injection, Cross Site Scripting, Locale File Inclusion, etc

In this scenario we use Owasp Core rules set (CRS) v3. First download CRS v3 on SpiderLabs git

sudo git clone

The command above will create new owasp-modsecurity-crs directory, then you should move owasp-modsecurity-crs folder to modsecurity.d folder :

sudo mv owasp-modsecurity-crs /etc/httpd/modsecurity.d/

De-activate the default CRS by giving the # on the lines, then add new line of crs v3 configuration:

# New Owasp CRS v2

Include modsecurity.d/owasp-modsecurity-crs/crs-setup.conf
Include modsecurity.d/owasp-modsecurity-crs/rules/*.conf

# Default CRS (deactivated)
# IncludeOptional modsecurity.d/*.conf
# IncludeOptional modsecurity.d/activated_rules/*.conf

Ensure your configuration should be like this: 

<IfModule mod_security2.c>
    # ModSecurity Core Rules Set configuration

        Include modsecurity.d/owasp-modsecurity-crs/crs-setup.conf
        Include modsecurity.d/owasp-modsecurity-crs/rules/*.conf

        #IncludeOptional modsecurity.d/*.conf
        #IncludeOptional modsecurity.d/activated_rules/*.conf

    # Default recommended configuration
    SecRuleEngine On
    SecStatusEngine on

    SecRequestBodyAccess On
    SecRule REQUEST_HEADERS:Content-Type "text/xml" \
    SecRequestBodyLimit 13107200
    SecRequestBodyNoFilesLimit 131072
    SecRequestBodyInMemoryLimit 131072
    SecRequestBodyLimitAction Reject
    SecRule REQBODY_ERROR "!@eq 0" \
    "id:'200001', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
    SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
    "id:'200002',phase:2,t:none,log,deny,status:44,msg:'Multipart request body \
    failed strict validation: \

    "id:'200003',phase:2,t:none,log,deny,status:44,msg:'Multipart parser detected a possible unmatched boundary.'"

    SecPcreMatchLimit 1000
    SecPcreMatchLimitRecursion 1000

    SecRule TX:/^MSC_/ "!@streq 0" \
            "id:'200004',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"

    SecResponseBodyAccess Off
    SecDebugLog /var/log/httpd/modsec_debug.log
    SecDebugLogLevel 0
    SecAuditEngine RelevantOnly
    SecAuditLogRelevantStatus "^(?:5|4(?!04))"
    SecAuditLogParts ABIJDEFHZ
    SecAuditLogType Serial
    SecAuditLog /var/log/httpd/modsec_audit.log
    SecArgumentSeparator &
    SecCookieFormat 0
    SecTmpDir /var/lib/mod_security
    SecDataDir /var/lib/mod_security

Next, you must rename  crs-setup.conf.example to  crs-setup.conf on owasp-modsecurity-crs folder :

sudo mv /etc/httpd/modsecurity.d/owasp-modsecurity-crs/crs-setup.conf.example /etc/httpd/modsecurity.d/owasp-modsecurity-crs/crs-setup.conf

Then if you can see all rules of CRS v3 in /etc/httpd/modsecurity.d/owasp-modsecurity-crs/rules/ directory.

If you want to disable the rules just rename it. For example :

sudo mv /etc/httpd/modsecurity.d/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf /etc/httpd/modsecurity.d/owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf.disable

The command above will disable rule REQUEST-920-PROTOCOL-ENFORCEMENT. To make a change you must restart the httpd service

sudo service httpd restart

This is final step, now you can test your Modsecurity with the CRS by input some simple attack like sql injection to your web page.

And if everything fine, you will see the something like this on the response page.

Congratulations you already installing WAF on your web application server with free. This is important for you to modify the rules so it can be suitable with your web application need, because some rule maybe have a conflict with your web application, WAF may able to block your web application request / response.

OK thats all, hope this useful for you, anay questions feel free to mail me.

Leave a Reply

Your email address will not be published. Required fields are marked *