I have a modsecurity with Core Rule Set. And I have POST-request with 3 parameters: Par1 = "base64-encoded XML "& Par2 = "url" & Par3 = "hash".

I want to modificate CRS rules to base64Decode only Par1 and use Par2 & Par3 'as is'.

I tried to use SecRuleUpdateActionById directive, but it requires to write a directive for every rule in CRS. SecDefaultAction directive does not work too, because all CRS-rules have "t:none" that overrides default actions. I also found multiMatch action, but I think it will cause a lot of false positives on base64-string.

Is there some way to update actions for multiple rules without rewriting this rules?


I found a solution. I decided to get the value of the parameter Par1, base64-decode it and record in a "TX" variable. This variable will be available until the transaction is complete. There are two ways to do it.

1.1. use lua:

  • create file extract_param.lua with a similar content:

    function main()
        -- Retrieve par1
        local par1 = m.getvar("ARGS.Par1", {"base64DecodeExt"});
        if par1 == nil then
            m.log(3, "no Par1 in request.");
            return nil;
        m.log(3, "Par1 base64-decoded:" ..par1.. ".");
    return nil;
  • add SecRuleScript directive before CRS is loaded:

    SecRuleScript path/to/script/extract_param.lua phase:2,log

1.2. use standard "setvar" functionality. This method is easier, I use it. But I found it (here) later and decided to tell about lua too.

  • add the following rule before CRS is loaded:

    SecRule ARGS:par1 "^(.*)$" "log, pass, id:22, phase:2, t:base64DecodeExt, setvar:tx.par1=%{MATCHED_VAR}"

2.add the bunch of SecRuleUpdateTargetByTag directives after CRS is loaded:

SecRuleUpdateTargetByTag 'OWASP_CRS/WEB_ATTACK/SQL_INJECTION' "!ARGS:par1|TX:par1"

It is not easy to update the action of multiple CRS rules, short of listing each rule id for the reasons you have given.

It is possible to update the variables matched for a group of rules using SecRuleUpdateTargetByTag but not the action as there is no SecRuleUpdateActionByTag (only a SecRuleUpdateActionById) but to be honest even if there was the fact you only want to transform 1 of your variables is going to cause you problems. And I agree multi match is probably not the right answer here even if you could do that.

Ultimately what I would recommend is to:

  1. Leave the rules as is and basically ignore the base64 par1 variable for the CRS (note you may need to update SOME rules to ignore this parameter for certain rules if the base64 coding is creating false positives).

  2. Decide what the attack vectors are for your par1 XML variable and write (or copy from the CRS) a smaller subset of rules just for this, with a base64Decode transformation. Even when base64 decoded, I would imagine the XML could create a lot of false positives still, so you probably do not want to run the full CRS on them anyway.

Good luck!

  • thanks for reply! but copying rules from the CRS suggests that after the CRS update we will need to update or rewrite those rules separately. my solution is more handy. – Vladimir Nov 9 '16 at 9:23
  • Nice workaround! Have an upvote from me. – Barry Pollard Nov 9 '16 at 10:06

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.