ModSecurity WAF: OWASP CRS Implementation Guide
ModSecurity is an open-source Web Application Firewall (WAF) that inspects HTTP requests and responses to block OWASP Top 10 vulnerabilities including SQL Injection, XSS, and file upload attacks.
Installing ModSecurityβ
ModSecurity for Nginxβ
# Ubuntu 22.04+
sudo apt install libmodsecurity3 libmodsecurity-dev
# Nginx module (dynamic module)
sudo apt install libnginx-mod-security2
# Or compile from source:
# git clone --depth 1 -b v3/master https://github.com/SpiderLabs/ModSecurity
# ./build.sh && ./configure && make && sudo make install
# Verify module is activated
nginx -V 2>&1 | grep ModSecurity
ModSecurity for Apacheβ
# Ubuntu
sudo apt install libapache2-mod-security2
sudo a2enmod security2
sudo systemctl restart apache2
# Verify installation
apache2ctl -M | grep security2
# security2_module (shared)
Installing OWASP Core Rule Set (CRS)β
# Download CRS (latest version)
cd /etc/nginx # or /etc/modsecurity
sudo git clone --depth 1 https://github.com/coreruleset/coreruleset.git /etc/modsecurity/crs
# Copy default configuration file
sudo cp /etc/modsecurity/crs/crs-setup.conf.example \
/etc/modsecurity/crs/crs-setup.conf
sudo cp /usr/share/modsecurity-crs/modsecurity.conf-recommended \
/etc/modsecurity/modsecurity.conf
ModSecurity Nginx Configurationβ
# /etc/nginx/nginx.conf β http block
http {
# Enable ModSecurity
modsecurity on;
# Configuration file path
modsecurity_rules_file /etc/nginx/modsecurity/main.conf;
}
# /etc/nginx/modsecurity/main.conf
# Include base ModSecurity configuration
Include /etc/modsecurity/modsecurity.conf
# Include OWASP CRS configuration
Include /etc/modsecurity/crs/crs-setup.conf
# Include CRS rule files
Include /etc/modsecurity/crs/rules/*.conf
Detection Mode vs Prevention Modeβ
# /etc/modsecurity/modsecurity.conf
# Detection Only mode: detects attacks, does not block
SecRuleEngine DetectionOnly
# Prevention mode: detects and blocks attacks
SecRuleEngine On
# Disabled
SecRuleEngine Off
Recommended deployment order:
- Start with
DetectionOnlyβ analyze logs β verify false positives - Configure exclusions for false positive rules
- Switch to
On
Handling False Positivesβ
When legitimate requests are blocked, exclude specific rules.
# /etc/modsecurity/custom-exclusions.conf
# Disable specific rule IDs
SecRuleRemoveById 942100 # SQL Injection detection rule (if false positive)
SecRuleRemoveById 941100 # XSS detection rule
# Exclude rules for specific URIs
SecRule REQUEST_URI "@beginsWith /api/editor/" \
"id:1001,phase:1,pass,nolog,\
ctl:ruleRemoveById=941100"
# Exclude rules for specific parameters (HTML parameters in body)
SecRuleUpdateTargetById 941100 "!ARGS:content"
# IP whitelist (internal development server)
SecRule REMOTE_ADDR "@ipMatch 10.0.0.0/8" \
"id:1000,phase:1,allow,nolog,ctl:ruleEngine=Off"
ModSecurity Log Analysisβ
# Audit log location (default)
cat /var/log/modsec_audit.log
# Check blocked requests
grep "Access denied" /var/log/modsec_audit.log | head -20
# Frequency analysis of triggered rule IDs
grep "id \"" /var/log/modsec_audit.log | \
grep -o 'id "[0-9]*"' | sort | uniq -c | sort -rn | head -20
# Also check in Nginx error log
grep "ModSecurity" /var/log/nginx/error.log | tail -20
CRS Paranoia Levelsβ
OWASP CRS provides 4 paranoia levels.
# /etc/modsecurity/crs/crs-setup.conf
# Paranoia Level settings
# 1: Basic (few false positives, recommended starting point)
# 2: More rules (some false positives possible)
# 3: Strict (use caution in production)
# 4: Maximum (very many false positives, for special environments)
SecAction \
"id:900000,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.paranoia_level=1"
Apache ModSecurity Configurationβ
# /etc/apache2/mods-available/security2.conf
<IfModule security2_module>
# Include configuration files
IncludeOptional /etc/modsecurity/*.conf
# OWASP CRS
IncludeOptional /etc/modsecurity/crs/crs-setup.conf
IncludeOptional /etc/modsecurity/crs/rules/*.conf
</IfModule>
# Disable ModSecurity for a specific virtual host
<VirtualHost *:443>
ServerName internal.example.com
# Disable ModSecurity only for this VirtualHost
SecRuleEngine Off
</VirtualHost>
ModSecurity Performance Tuningβ
# /etc/modsecurity/modsecurity.conf
# Minimize audit logging (improve performance)
SecAuditEngine RelevantOnly # Log only blocked requests
SecAuditLogParts ABIJDEFHZ # Log only necessary parts
# Request body inspection size limit
SecRequestBodyLimit 13107200 # 12.5 MB
SecRequestBodyNoFilesLimit 131072 # 128 KB (body excluding files)
# Response body inspection (high performance cost, enable only when needed)
SecResponseBodyAccess Off # Disabled by default
# Rule engine parallelization
SecPcreMatchLimit 500000
SecPcreMatchLimitRecursion 500000