Search code examples
mod-securitymod-security2

Modsecurity: removeWhitespace not working


I have the following rule:

 SecRule REQUEST_HEADERS:Client-IP "@ipMatchFromFile test.txt" 
"id:210487,t:none,t:urlDecodeUni,t:removeWhitespace,drop,msg:'IP-test'"

But When I run it I get the response:

T (0) urlDecodeUni: "111.22.33.44 " // note the space before the "
T (0) removeWhitespace: "111.22.33.44"  // perfect! The space has been removed
Transformation completed in 4 usec.
Executing operator "ipMatchFromFile" with param "test.txt" against REQUEST_HEADERS:Client-IP.
Target value: "111.22.33.44"  // target value has no space, hooray!
IPmatchFromFile: Total tree entries: 8, ipv4 8 ipv6 0
IPmatch: bad IPv4 specification "111.22.33.44 ".  // why, oh why, is the space back!
Operator completed in 4 usec.
Operator error: IPmatch: bad IPv4 specification "111.22.33.44 ".  // that space again!
Rule returned -1.
Rule processing failed.
Rule failed, not chained -> mode NEXT_RULE.

Please Stack Overflow legends; show me how I can fix it :-)


Solution

  • That should work, so looks like a bug. Can't say I've honestly tried to match an IP address that required transformation first.

    Since it's not really an IP address you could switch to using @pmFromFile rather than @ipMatchFromFile. Note that the documentation warns explicitly that you need to use boundaries correctly here:

    Because this operator does not check for boundaries when matching, false positives are possible in some cases. For example, if you want to use @pm for IP address matching, the phrase 1.2.3.4 will potentially match more than one IP address (e.g., it will also match 1.2.3.40 or 1.2.3.41). To avoid the false positives, you can use your own boundaries in phrases. For example, use /1.2.3.4/ instead of just 1.2.3.4. Then, in your rules, also add the boundaries where appropriate. You will find a complete example in the example:

    # Prepare custom REMOTE_ADDR variable 
    SecAction "phase:1,id:168,nolog,pass,setvar:tx.REMOTE_ADDR=/%{REMOTE_ADDR}/"
    
    # Check if REMOTE_ADDR is blacklisted 
    SecRule TX:REMOTE_ADDR "@pmFromFile blacklist.txt" "phase:1,id:169,deny,msg:'Blacklisted IP address'" 
    

    The file blacklist.txt may contain:

    # ip-blacklist.txt contents:
    # NOTE: All IPs must be prefixed/suffixed with "/" as the rules
    #   will add in this character as a boundary to ensure
    #   the entire IP is matched.
    # SecAction "phase:1,id:170,pass,nolog,setvar:tx.remote_addr='/%{REMOTE_ADDR}/'"
    /1.2.3.4/ 
    /5.6.7.8/