I'm using ModSecuity with my Apache server, and I want to set it to not log requets who has a determineted parameter in querystring.
In mod_secuirty.conf, I have this following configs:
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
And I want to set somethint like SecAuditLogRelevantParameter "?!(test)" (to log any request who doen't have the test parameter).
mod_security2 for Apache supports the ctl:auditLogParts and ctl:auditLogEngine (note: libmodsecurity3 does not support auditLogEngine sub-action for ctl). Thus you can make a rule, that turns off the audit engine, or modify the log parts. I think you want to turn it off, so based on your request you need something like this:
SecAction
"id:111001,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.args_contains_test=0"
SecRule ARGS_NAMES "@rx test" \
"id:111002,\
phase:2,\
pass,\
nolog,\
t:lowercase,
setvar:'tx.args_contains_test=1'"
SecRule TX:args_contains_tests "@lt 1"
"id:111003,\
phase:2,\
pass,\
nolog,\
ctl:auditLogEngine=Off"
Put these rules to the very beginning of your rule set - if you use CRS, then the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf is a good choice.
How this exclusion works?
As you wrote above, the condition is "any request who dosen't have the test parameter". This is not so trivial, because you have to check that something is not exists, therefore you have to inspect all arguments.
In ModSecurity, you can do it only whit this way above: first, you have to set up a transaction variable, which stores the information, the request contains any argument with name test or not. That's the first (and only) SecAction.
@rx test is a ModSecurity operator and its argument, that checks the ARGS_NAMES collection. This collection contains all of the request's arguments. The rule 111002 checks all argument names, and if there are any variable with name like test (regex matches), then it changes the TX variable.
The rule 111003 checks the TX variable, and if it's 1, then disables the auditLog engine for the current transaction. That's it.
Please note, that the @rx operator is case-sensitive, that's why the t:lowercase is there.
Also note, that the two SecRules executed in phase:2. If you want to check the GET parameter, then you have to move this rule to phase:1. If you want to check all possible variables, then you have to duplicate this rule: one for the phase:1 and the other one for phase:2 - with a unique id!
If you want to turn off the auditLogEngine with a QUERY_STRING parameter, eg. http://example.com/form.cgi?test=1, then the solution is more simple - but anyone can turn off at this way:
SecRule REQUEST_URI "@endsWith test=1" \
"id:111001,\
phase:1,\
pass,\
nolog,\
t:lowercase,\
ctl:auditLogEngine=Off"