Note that besides copying setup files we edit inline modsecurity.conf to make sure SecRuleEngine is set to On instead of DetectionOnly (switch between them to activate the rules or just get logging information) and to make sure SecAuditLogRelevantStatus is set to "^$" instead of "^(?:5|4(?!04))" (switch between them to get log entries when the application returns 4xx or 5xx status codes or not log them at all)
This recipe will activate sql and command injection protection rules. There are several other core rules you can add just by copying them to /etc/modsecurity and restarting the server after. There are base_rules, experimental_rules and optional_rules distributed in the ModSecurity project.
To test the effectiveness of sql injection protection do not activate the rule (remove the specific crs file from the /etc/modsecurity directory), restart the server and try the below request. Apache will pass it request to your application as usual
https://sample.com/foo?bar=%27%20or%20true%20--Now activate the rule (put the specific crs file in the /etc/modsecurity directory), restart the server and try the same request. You receive a Forbidden status code (403). From logs (/var/log/modsec_audit.log) you can read:
Message: Access denied with code 403 (phase 2). Pattern match "(^[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98;]+|[\"'`\xc2\xb4\xe2\x80\x99\xe2\x80\x98;]+$)" at ARGS:a. [file "/etc/modsecurity/modsecurity_crs_41_sql_injection_attacks.conf"] [line "64"] [id "981318"] [rev "2"] [msg "SQL Injection Attack: Common Injection Testing Detected"] [data "Matched Data: ' found within ARGS:a: ' or true --"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.8"] [maturity "9"] [accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/6.5.2"] Action: Intercepted (phase 2)The recipe also activates command injection which you can test as described above using the below url:
https://sample.com/foo?bar=curlThis is a fairly simple setup which I would consider basic to secure any production web application.
You might need to add exclusions for certain non compliant and existent URLs. Since developers could take take a while to fix several existent issues and you do not want to delay the Firewall protection here are some guidelines to smooth the installation and produce your MMF ASAP.
Set 'SecRuleEngine DetectionOnly' so that you can compile the current problems from the log file:
sudo sed -i 's/^SecRuleEngine.*/SecRuleEngine DetectionOnly/' /etc/modsecurity/modsecurity.conf && sudo apachectl graceful
Find the modsecurity rule id for issues so far:
cat /var/log/apache2/yourlogname.log|grep ModSecurity|grep -o 'id "[0-9]*"'|sort|uniq
Look into each error to look into URLs needing exceptions and what it is all about. For example for id 981240:
cat /var/log/apache2/yourlogname.log | grep ModSecurity | grep 981240Also look into the definitive modsecurity log to confirm if in doubt:
sudo less /var/log/modsec_audit.log
# Using 25 MB for upload limit SecResponseBodyLimit 26214400 # Exceptions for URLs that violate PCRE limits, dangerous characters accepted and parameters too long SecRule REQUEST_URI "@contains /path/containing/service/accepting/long/parameters/content/and/literal/code/and/others "phase:1,t:none,pass,id:'1',nolog,ctl:ruleRemoveById=959070,ctl:ruleRemoveById=960024,ctl:ruleRemoveById=981173,ctl:ruleRemoveById=950901,ctl:ruleRemoveById=981231,ctl:ruleRemoveById=981240,ctl:ruleRemoveById=981243,ctl:ruleRemoveById=981245,ctl:ruleRemoveById=981318"
SecRule REQUEST_BASENAME "@contains blogs" "id:1,ctl:ruleEngine=Off"
sudo sed -i 's/^SecRuleEngine.*/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf && sudo apachectl graceful