Recently I had following technical issue: In the system where 2 complex solution pass information using SOAP requests, I had to make sure, that one of those system don’t use one specific function (for security reason). Unfortunately there wasn’t any way, how I can prevent the use of such function directly on the server which receives the request.
Solution quite suprised me. It is possible to put an apache server in reverse proxy mode between those 2 systems and make it block a requests which contain specific world. To do that, I had to configure mod_security module. That is quite awsome swiss knife. In matter of fact, you can do quite complex scripts running on top of http connections. For instance, there are default configs which can prevent operation of the most of well knows worms and trojans in your network. With mod_security, you can turn apache into quite powerful „antivirus/firewall“ on top of http connections.
Lets take a look at a solution I used in my vhost configuration:
LoadModule security2_module modules/mod_security2.so
# mod_security setting to reject call of DeleteThemAll function
SecRuleEngine On
SecRequestBodyAccess On
# Debug log
SecDebugLog $(APACHE_ROOT)/logs/modsec_debug.log
# details of how transactions are handled including information about each piece of information handled
SecDebugLogLevel 6
SecAction "phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=URLENCODED"
SecRule REQUEST_BODY "@pm DeleteThemAll" "phase:2,id:5001,log,deny,status:403,msg:'Function DeleteThemAll() not permitted!'"
First few directives are just to turn on mod_security. Key are 2 last directives. First is unconditional action saying that always during phase 1 (which is parsing of the request headers) we going to set BodyProcessor to URLENCODED. This is needed, otherwise second directive won’t work!
Second directive then do the job. It is saying this: when ever you see in REQUEST_BODY word DeleteThemAll, it return to requestor HTTP status 403 and to log put custom message with ID 5001.
This is the log entry you going to see:
[Wed Jan 29 12:54:03 2014] [error] [client 10.0.0.1] ModSecurity: Access denied with code 403 (phase 2). Matched phrase "DeleteThemAll" at REQUEST_BODY. [file "mod_perl"] [line "83"] [id "5001"] [msg "Function DeleteThemAll() not permitted!"] [hostname "my-service-server"] [uri "/ServiceProvider"] [unique_id "Aaaa1aa2AaAAAB33A4aAAAAA"]
Attention! it won’t work with substring – for instance if requestor call function DeleteThemAllTwice, it is going to pass thru. If you need more complex rules, you can use default operator @rx, but keep in mind, that the evaluation will be bit more demanding from performance point of view.
Good read where to start when you need to achieve something is the mod_security reference manual or this presentation. In case you need to learn all the power of this module, I strongly recommend the book ModSecurity Handbook: The Complete Guide to the Popular Open Source Web Application Firewall by Ivan Ristic. That really show how complex your rules can be.