Blog: How-Tos

WAF (Web Application Firewall) Testing for dummies

Minh-dat Lam 08 Apr 2014

The use of a Web Application Firewall can add an additional layer of security to your current web site. However, it can be dangerous to solely rely on a WaF alone!

Therefore, before reading this blog, ensure that you have a good security foundation to your website’s coding practices and the rest will fall into place.

The idea is to use the WaF as a safety net in case bugs were missed or through the introduction of new code etc.

Right, let’s skip to the juicy information as you most probably know what a WaF is and how basic web security works etc.

First and foremost, you will want a quick and efficient way of testing your WaF. Ideally, you will have your web site deployed and your WaF sitting nicely in front of that website – protecting you from the big bad world.

You should also understand who your primary threats are, your surrounding infrastructure, what hosts are potentially whitelisted and what traffic is sent to your web site, this may include additionally traffic from web services such as SOAP etc.

Testing stages

Generally, several initial configurations are possible when first deploying your WaF. These configurations can be somewhat tedious as you need to learn/add URLs and parameters to your WaF. Therefore, following methodical test routines will hopefully help you understand your WaF at a more granular level.

These stages can for example, include the following configuration states:

  • Default no configuration settings – No WaF protection at all.
  • Simple URL restriction policy – Restrictions for URL access only.
  • Simple URL restrictions & parameter checking – URL restriction and parameter inspection.
  • Simple URL restrictions & parameter checking for basic HTTP traffic – All the above with specific malicious traffic inspection (this will be listed below in the attack types).
  • Simple URL restrictions & parameter checking for basic JSON/SOAP specific traffic – Same as the above, however, may also be required if your application uses specific web services.
  • File upload checking – finally, file upload facilities should be inspected for malicious content.

Attack types

As mentioned in the testing stages, these specific tests will need to include some of the more fun requests! Try throwing the following into your requests:

  • Popular attack signatures – encoded and non-encoded SQL injection, XSS, OS Injection, LDAP Injection, XML Injection, Path Traversal, Local File Inclusion, Remote File Inclusion etc.
  • Header manipulation techniques – attacking cookie/referer/host headers etc.
  • JSON/SOAP schema bypass techniques.
  • Masked data – shikata_ga_nai and Base64 encoding etc.
  • File scanning manipulation – masked and unmasked anti-virus and malware signatures.

A few examples of these test scenarios using ModSecurity are provided below (edit the mod_security.conf on the fly whilst testing):

Simple buffer size checking for POST requests:

SecRequestBodyAccess On
SecRequestBodyLimit 10000

This should thwart against buffer overfly style attacks within the “Simple URL restrictions & parameter checking for basic HTTP traffic test” scenario.

Simple XML schema checking:

SecRule REQUEST_HEADERS:Content-Type “text/xml”
“id:’1′,phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML”

This should enforce a base XML schema for your web service as suggested within the “This should Simple URL restrictions & parameter checking for basic JSON/SOAP specific traffic” test.
Rather than listing a huge amount of scenario configuration states, many comprehensive lists can be found online, an example being:
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

Example test cases

This is probably the most common and an easy to make mistake when configuring a WaF.
We’ve seen many websites with perfect URL and Parameter filtering, however, oversights were seen within the HTTP header fields, such as cookie value.

This may not seem like a big deal at first, however, flaws such as SQL injection may be possible within these HTTP header fields:

POST http://testwebsite.com/search HTTP/1.1
Host: testwebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://testwebsite.com/home
cookie: <INSERT SQL INJECTION HERE>

Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

search=test

Additionally, some WaF implementations use header values to identify/block/whitelisted specific internal servers, as many people integrate their WaF with caching services or devices. Therefore manipulating these may allow you to bypass the WaF completely.

These whitelists could allow all traffic originating from a specific IP to pass unchecked and by default some WaFs will even whitelist their own IPs!

By setting the X-originating-IP: 127.0.01 for example, may allow all your traffic to bypass the WaF completely. There are also additional Headers that may be in use so try and enumerate them all:

POST http://testwebsite.com/search HTTP/1.1
Host: testwebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://testwebsite.com/home
cookie: abc
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
X-forwarded-for: <INSERT SPOOFED IP TO BYPASS WAF COMPLETELY>search=test

Character limit oversights

Some WaFs have a character limits for a parameter checking, this can be bypassed by inserting a very large buffer space to potentially insert your attack string:

POST http://testwebsite.com/search HTTP/1.1
Host: testwebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://testwebsite.com/home
cookie: abc
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 548

junk=AAAAAAAAAAAAA&search=<INSERT ATTACK STRING HERE>

Case sensitivity

Case sensitivity is also another bypass technique. Regular expressions that may be set should incorporate case sensitivity:

POST http://testwebsite.com/search HTTP/1.1
Host: testwebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://testwebsite.com/home
cookie: abc
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 35search=<InSeRt AtTaCk StRiNg HeRe>

This method of evasion is implemented by sqlmap’s tamper/randomcase.py script for example, if you are trying to perform a SQL injection attack.

Oversight of filter list

Finally, this type of oversight may involve simply missing sets of “bad” characters or Unicode. Again, rather than listing all the types of bypass characters and encodings in this blog, you can simple have a search around for a comprehensive list. These are readily available and very easy to find.
Here is a link to get you started: http://www.exploit-db.com/papers/17934/

Remember, when you are filtering, it is much better to allow known safe characters to pass through the filter, rather than trying to enumerate all the bad things to keep out.

Summary

Also remember, don’t stick a WaF in front of a flaky application and expect it to be secure. Maybe if you have vulnerable business critical applications that you are replacing soon, a WaF can provide a temporary stopgap.

A WaF is just one of many layers of protection. Install it, configure it, understand it, and test it!