Three ModSecurity Rule Language Annoyances

There are three aspects of the ModSecurity Rule Language we are not very happy with. One comes from a wrong design decision (my own), with further two from constraints of working within the framework of Apache. All three break the principle of the intuitive action being the expected one. I am going to document them here and explain how we are planning to mitigate them in future versions:

  1. In a chain starter rule, disruptive actions are processed when the chain matches, but non-disruptive actions are processed when the rule matches. In other words, it is only the disruptive actions that are treated differently in chains, all other action types behave as they would in standalone rules. Have a look at the following:

    SecRule T1 K1 chain,log,block,setvar:tx.counter=+1
    SecRule T2 K2
    In the example above the counter will be incremented if the first rule matches even if the chain doesn't. The blocking action, although defined with the same rule, would only be processed if both the first rule and the second rule match.

    In retrospective, disruptive actions for chains should have been placed with the last rule in a chain, not with the first one. If it is possible to move to that mechanism in the next major version while preserving compatibility with existing configurations we will do that.

  2. SecDefaultAction is valid only for the configuration context in which it is used and is not inherited in child contexts. Configuration contexts are an Apache feature and they come with limitations, one of which is causing this problem.
    SecDefaultAction log,deny
    SecRule T1 K1
    <Location /some/other/path>
    SecRule T2 K2
    </Location>
    In the above example, the first rule blocks, but the second one just uses the ModSecurity defaults and only warns and lets requests through.

    In the next major version of ModSecurity (v3) we will handle our configuration ourselves and this problem will probably go away. In fact, the SecDefaultAction directive might be made obsolete in the next major version because we don't like it much. In retrospective, it was a wrong choice too. It is good practice to write rules to be self-contained. That way they will be easier to understand and maintain, and you don't risk configuration errors due to something being changed in the configuration elsewhere.

  3. Configuration contexts other than <VirtualHost> cannot hold phase 1 rules. Again, this is a limitation of the current implementation that relies on Apache for configuration functionality.

    Short term (e.g. 2.6), we are planning to see if we can detect phase 1 rules in places where they cannot be run and respond with an configuration error. The problem will go away once we start handling our own configuration.

Trustwave reserves the right to review all comments in the discussion below. Please note that for security and other reasons, we may not approve comments containing links.