Modsec: Set env variable based on User-agent

apache-2.2mod-security

Relatively new to Apache modsec. Trying to do something simple and hitting a wall. I want to set an environment variable based on the User-Agent, and test it by setting a header. I have this:

SecRule HTTP_User_Agent "Gecko" "phase:2,nolog,setenv:MOZTEST=1,id:100000025"
Header always set MozTest "1" env=MOZTEST

Figured that in Firefox, the MozTest header should be set, but it's not. I also tried REQUEST_HEADERS:User-Agent in place of HTTP_User-Agent, but still no effect. Also tried increasing the phase to 5, even though it should have the user agent at phase 2. There is no error; the rule just doesn't seem to fire.

My guess is that the user-agent variable isn't set, but I don't know why. (Or even how to test that, as I've never had to do any custom logging.)

Best Answer

Came across my own question while researching another issue years later.

It appears the main issue here is that I was trying to use a mod_rewrite variable (HTTP_USER_AGENT) in a mod_security context. Instead I could have either used the correct ModSecurity variable (REQUEST_HEADERS:User-Agent) or passed the mod rewrite variable as an environment variable (not that there's a good reason to do that when a ModSecurity alternative is available.)

So my example above should look like this:

SecRule REQUEST_HEADERS:User-Agent "Gecko" "phase:2,nolog,setenv:MOZTEST=1,id:100000025"
Header always set MozTest "1" env=MOZTEST

A full list of variables available to ModSecurity is here: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#Variables

Alternatively—not useful in this case, but perhaps valuable to note for other circumstances—I could have used mod rewrite to dump the user agent into an environment variable, then matched on that with mod security, like this:

RewriteRule .* - [E=user_agent:%{HTTP_USER_AGENT}]
SecRule ENV:user_agent "Gecko" "phase:2,nolog,setenv:MOZTEST=1,id:100000025"
Header always set MozTest "1" env=MOZTEST