I'm trying to set up mod_security to log POST requests payload for a specific URI, as it seems that a customers webpage is used as a spam relay and these requests corrupt the server side cache.

I started by following this blog post but it seems rather old and outdated. It's not working with our environment which is Apache 2.4 and mod_security 2.8. So I enhanced that config by this serverfault answer.

Inside the relevant vhost config mod_security is configured like this:

<IfModule security2_module>
    SecRuleEngine On
    SecAuditEngine RelevantOnly
    SecAuditLog logs/audit.log
    SecRequestBodyAccess On
    SecAuditLogParts ABCFHJKZ

    SecDefaultAction "phase:2,nolog,noauditlog,pass"

    SecRule REQUEST_METHOD "^POST$" "id:'1234',phase:2,chain,allow,ctl:auditEngine=On"
    SecRule REQUEST_URI "^\/en\/us\/$"

The result is that every POST request is logged into audit log. But only the POST request to the homepage https://<SITE>/en/us/ should be logged. In my understanding this should be done by chaining to the second SecRule which matches the request URI against the given regex. I also tried different versions of the regex without success.


It's a little confusing but some of the actions specified in the first rule will run for each rule matched in the chain and some only if all rules match (the author of ModSecurity has stated in hindsight it would have been better to put the rules on the last chained rule rather than the first). See here for more details: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#chain:

Special rules control the usage of actions in chained rules:

  • Any actions that affect the rule flow (i.e., the disruptive actions, skip and skipAfter) can be used only in the chain starter. They will be executed only if the entire chain matches.
  • Non-disruptive rules can be used in any rule; they will be executed if the rule that contains them matches and not only when the entire chain matches.
  • The metadata actions (e.g., id, rev, msg) can be used only in the chain starter.

So rule should be this so logging is only turned on when first and second rule matches:

SecRule REQUEST_METHOD "^POST$" "id:'1234',phase:2,chain,allow"
SecRule REQUEST_URI "^\/en\/us\/$" "ctl:auditEngine=On"

Note also this will allow the rule and skip all future rules. You might be better to pass the rule instead. That way it will definitely be logged but still run other rules. However if this is your only rule as per the config you've shown it won't really matter, but still good practice.

  • I kept playing around with the rules and actions and at a certain point I noticed somenthing inconsistencies: I used the following rules: SecRule REQUEST_METHOD "^POST$" "id:'1',phase:2,chain" SecRule REQUEST_URI "@streq /us/en/" "ctl:auditEngine=On,auditlog" but in the logs K section these rules are listed: SecRule "REQUEST_METHOD" "@rx ^POST$" "phase:2,nolog,noauditlog,id:8151,chain" SecRule "REQUEST_URI" "@streq /us/en/" "ctl:auditEngine=On" Somehow nolog and noauditlog are set automaticly to the first rule and noauditlog is removed from the second. – ahaertig Feb 2 '16 at 13:29
  • They are different rules. One is id:1 and one is id:8151. Also very difficult to read in comments so please add to question or raise a new question. – Barry Pollard Feb 2 '16 at 20:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.