Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How to configure the simplest useful default-deny rule set for mod_security?

I want to configure mod_security to allow only very specific queries to single directory:

In short: I use Apache as a reverse proxy for directory /web_app/, in this directory will be a single php file named get.php. I want to pass to this script only queries that match the following regular expression:

get\.php\?ver=1&id=[a-f\d]{16,16}&v=[-.a-z\d\ ]{1,20}

In other words, queries with three fields only: id, ver and v. Where first is a digit 1, the second a 16 digit hexadecimal and the third is a string at most 20 characters long with letters, numbers, dots, hyphens and space. It has to deny or remove from queries anything but POST and GET values, that is: file uploads, cookies, all non-essential headers, values other than the 3 specified, etc...

I don't want to change the way any other directories work, just /web_app/. Filtering out wrong UTF or URL escaping/encoding is not a problem, so enabling mod_security shouldn't be a problem in itself.

share|improve this question
Why? This is the job of your script. It ignores all other variables and it must check the content. Don't delegate variable checking to an external module. – mailq Aug 21 '11 at 14:05
@mailq: It's a reverse proxy, I provided PHP as an example, I'll be using it also with .NET, Java and Ruby. Besides, that's exactly what web application firewalls are for -- to double check that the application won't accept values it shouldn't. – Hubert Kario Aug 21 '11 at 14:11
@Hubert a web application firewall is there to protect you against attacks based on heuristics, not to do the work if the developers of the webapps – Thomas Berger Aug 21 '11 at 14:53
@Thomas: Are you suggesting that a "default deny" firewall won't be more effective? I know that this kind of firewall will be harder to configure for more complex applications, but then, I'll have to do it once, not constantly update the rules when new attack vectors come to life. Or do you configure your network firewall to drop only packets arriving on port 137, 138 and 445? Enumerating badness doesn't work anymore: – Hubert Kario Aug 21 '11 at 16:31
@Hubert i don't see what you want to tell me. For mod_security there are bulk of rulesets for the most common issues. But if you KNOW a that your application has a security problem, its common that there are even more problems and you should check and fix the app. If you could not because it's closed source, talk to the vendor, if your developers have no clue, fire them or give them some education... I didn't talked about a "default deny" firewall anywhere, did i? – Thomas Berger Aug 21 '11 at 16:53

For filtering the argumetns, there is a much simpler way then using regular expressions on the whole uri:

<Location /web_app>
  SecFilterSelective ARG_NAMES "!^(id|ver|v)$"
  SecFilterSelective ARG_ver   "!^1$"
  SecFilterSelective ARG_id    "!^[a-f\d]{16,16}"
  SecFilterSelective ARG_v     "!^[-\.a-z\d\ ]{1,20}"

  # Here the same for the request type
  SecFilterSelective REQUEST_METHOD "!^(GET|HEAD|POST)$"

Will match on any argument NOT in the list only under /web_app.

You could find good examples in the mod_security documentation:

All othere parameters could be found there also.

share|improve this answer
This lets through TRACE and OPTIONS request methods... Won't it also let through any Content-Type or Cookies? – Hubert Kario Aug 21 '11 at 19:08
Should i write you up the whole ruleset here? Ok, you could pay the usual price for security consulting. Go to the docs, you could do all the other rules here too. – Thomas Berger Aug 21 '11 at 19:12
The solution you provided still doesn't fulfill my rather straight-forward and simple requirements. If not for POST I could put it in a single regular expression for data and another for allowed headers! I couldn't find a way to reverse the way the mod_security rules work (let only specific arguments, headers and values) that's why I'm asking at serverfault. So yes, please write a full ruleset that I wrote in 4 lines of English, or a way to allow only specific headers the way you showed how to limit arguments. – Hubert Kario Aug 21 '11 at 19:30
added HEAD because you should allow that, your you'll break any caching functions on the remote ends. – Thomas Berger Aug 21 '11 at 19:37
You're right, it won't hurt. – Hubert Kario Aug 21 '11 at 20:31

I suppose you need something like this:

<LocationMatch "^/web_app/">
        SecRule REQUEST_URI "!(:?get\.php\?ver=1&id=([a-f\d]){16,16}&v=([-.a-z\d\ ]){1,20})" "id:123,phase:2, deny, status:406"

For the REQUEST_METHOD you could add one additional rule to block if REQUEST_METHOD doesn't match the method you want/allow.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.