Security – how to modificate modsecurity rule action for only one parameter

mod-securitySecurityweb-application-firewall

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?

Best Answer

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;
        end
        m.log(3, "Par1 base64-decoded:" ..par1.. ".");
        m.setvar("TX.Par1",par1);
    return nil;
    end
    
  • 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"
Related Topic