B Web Application Firewall Examples and Use Cases

The attack prevention feature of web application firewall stands between the client and origin servers. If the web application firewall finds a malicious payload, it will reject the request, performing any one of the built-in actions. This section provides some basic information about how web application firewall works and how some rules are used for preventing attacks.

Some of the features of web application firewall are audit logging, access to any part of the request (including the body) and the response, a flexible rule engine, file-upload interception, real-time validation and buffer-overflow protection.

Web application firewall's functionality is divided into four main areas:

  • Parsing: Parsers extract bits of each request and/or response, which are stored for use in the rules.

  • Buffering: In a typical installation, both request and response bodies are buffered so that the module generally sees complete requests (before they are passed to the application for processing), and complete responses (before they are sent to clients). Buffering is the best option for providing reliable blocking.

  • Logging: Logging is useful for recording complete HTTP traffic, allowing you to log all response/request headers and bodies.

  • Rule engine: Rule engines work on the information from other components, to evaluate the transaction and take action, as required.

Basics of Rules

The web application firewall rule engine is where gathered information is checked for any specific or malicious content.

This section provides information about basic rule-writing syntax, and rule directives for securing Web applications from attacks.

The main directive that is used for creating rules is SecRule. The syntax for SecRule is:

  • VARIABLES: Specify where to check in an HTTP transaction. Web application firewall pre-processes raw transaction data, which makes it easy for rules to focus on the logic of detection. A rule must specify one or more variables. Multiple rules can be used with a single variable by using the | operator.

  • OPERATORS: Specify how a transformed variable is to be analyzed. Operators always begin with an @ character, and are followed by a space. Only one operator is allowed per rule.

  • TRANSFORMATION_FUNCTIONS: Change input in some way before the rule operator is run. A rule can specify one or more transformation functions.

  • ACTIONS: Specify the required action if the rule evaluates to true, which could be, display an error message, step on to another rule, or some other task.

Here is an example of a rule:

SecRule ARGS|REQUEST_HEADERS "@rx <script" msg:'XSSAttack',deny,status:404
  • ARGS and REQUEST_HEADERS are variables (request parameters and request headers, respectively).

  • @rx is the regular expression operator. It is used to match a pattern in the variables.

    In the example, the pattern is <script.

  • msg, deny and status are actions to be performed if a pattern is matched.

    The rule in the example is used to avoid XSS attacks, which is done by checking for a <script pattern in the request parameters and header, and an XSS Attack log message is generated. Any matching request is denied with a 404 status response.

Rules Against Major Attacks

This section provides information about some rules that are used for preventing major attacks on Web applications.

Brute Force Attacks

Brute force attacks involve an attacker repeatedly trying to gain access to a resource by guessing usernames, passwords, e-mail addresses, and similar credentials. Brute force attacks can be very effective if no protection is in place, especially when users choose passwords that are short and easy to remember.

A good way to defend against brute force attacks is to allow a certain number of login attempts, after which the login is either delayed or blocked. Here is an example of how this can be accomplished using Oracle Traffic Director web application firewall.

If your login verification page is situated at yoursite.com/login and is served by the virtual server waf-vs, then the following rules, in waf-vs.conf file configured at the virtual server level, will keep track of the number of login attempts by the users:

# Block further login attempts after 3 failed attempts

# Initalize IP collection with user's IP address
SecAction "initcol:ip=%{REMOTE_ADDR},pass,nolog"

# Detect failed login attempts
SecRule RESPONSE_BODY "Unauthorized" "phase:4,pass,setvar:ip.failed_logins=+1,expirevar:ip.failed_logins=60"

# Block subsequent login attempts
SecRule IP:FAILED_LOGINS "@gt 2" deny

The rules initialize the IP collection and increment the field IP:FAILED_LOGINS after each failed login attempt. When more than three failed logins are detected, further attempts are blocked. The expirevar action is used to reset the number of failed login attempts to zero after 60 seconds, so the block will be in effect for a maximum of 60 seconds.

To use the persistent collection, IP, you should specify the path to store the persisted data using the SecDataDir directive. Since the scope of this directive is Main, it should be specified at the server level. This can be accomplished as follows:

# The name of the debug log file
SecDebugLog ../logs/brute_force_debug_log
# Debug log level
SecDebugLogLevel 3
# Enable audit logging
SecAuditEngine On
# The name of the audit log file
SecAuditLog ../logs/brute_force_audit_log
# Path where persistent data is stored
SecDataDir "/var/run/otd/waf/"

If this rules file is called waf-server.conf , <instance-dir>/config/server.xml would look like this:


Web application firewall and response body processing (equivalent of SecResponseBodyAccess directive) should be enabled for the /login URI in waf-vs-obj.conf. waf-vs-obj.conf would look like this:

<Object name="default">
<If $uri eq "/login">
AuthTrans fn="webapp-firewall" process-response-body="on"

After 3 failed attempts to login, audit log would have the following message:

[19/Mar/2013:05:06:57 --0700] ygfh3010000000000,0 49619 5021
GET /acl/acl02.html HTTP/1.1
user-agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
accept: */*
host: yoursite.com
authorization: Basic YWxwaGE6YmV0YQ==
HTTP/1.1 403 Forbidden
status: 403 Forbidden
content-length: 208
content-type: text/html
Message: Warning. Unconditional match in SecAction. [file "/waf-rules/waf-vs.conf"] [line "10"]
Message: Access denied with code 403 (phase 2). Operator GT matched 2 at IP:failed_logins. [file "/waf-rules/waf-vs.conf"] [line "25"]
Action: Intercepted (phase 2)
Stopwatch: 1363694817000000 898560 (- - -)
Stopwatch2: 1363694817000000 898560; combined=370, p1=14, p2=336, p3=0, p4=0, p5=19, sr=131, sw=1, l=0, gc=0
Producer: ModSecurity for Apache/2.6.7 (http://www.modsecurity.org/).
Server: Oracle Traffic Director/

SQL Injection

SQL injection attacks can occur if an attacker is able to supply data to a Web application that is then used in unsanitized form in an SQL query. This can cause the SQL query to do something that is completely different from what was intended by the developers of the Web application. For example, an attacker can try deleting all records from a MySQL table, like this:


This can be prevented by using the following directives:

SecDefaultAction "phase:2,log,auditlog,deny,status:403"
SecRule ARGS "(select|create|rename|truncate|load|alter|delete|update|insert|desc)\s*" "t:lowercase,msg:'SQL Injection'"

Whenever the web application firewall engine spots such a request, something similar to the following code is logged to audit_log:

[20/Mar/2013:02:58:35 --0700] Xkjx6010000000000,0 35971 5021
GET /acl/acl02.html?user=user1';DELETE%20FROM%20users-- HTTP/1.1
host: waf.test.com
connection: close
HTTP/1.1 403 Forbidden
status: 403 Forbidden
content-length: 208
content-type: text/html
connection: close
Message: Access denied with code 403 (phase 2). Pattern match "(select|create|rename|truncate|load|alter|delete|update|insert|desc)\\s*" at ARGS:user. [file "/waf-rules/sql_injection_attack.conf"] [line "2"] [msg "SQL Injection"]
Action: Intercepted (phase 2)
Stopwatch: 1363773515000000 668049 (- - -)
Stopwatch2: 1363773515000000 668049; combined=131, p1=8, p2=104, p3=0, p4=0, p5=19, sr=0, sw=0, l=0, gc=0
Producer: ModSecurity for Apache/2.6.7 (http://www.modsecurity.org/).
Server: Oracle Traffic Director/

In response to the attack, SecDefaultAction is applied. in which case the request is denied and logged, and the attacker receives a 403 error. If you would like a different action to take place, such as redirect the request to an HTML page with a customized warning content, specify it in the rule, as follows:

SecRule ARGS "(select|create|rename|truncate|load|alter|delete|update|insert|desc)\s*" "t:lowercase,msg:'SQL Injection',redirect:http://yoursite.com/invalid_request.html

XSS Attacks

Cross-site scripting (XSS) attacks occur when user input is not properly sanitized and ends up in pages sent back to users. This makes it possible for an attacker to include malicious scripts in a page by providing them as input to the page. The scripts will be no different from scripts included in pages by creators of the website, and will thus have all the privileges of an ordinary script within the page, such as the ability to read cookie data and session IDs.

Here is an example of a simple rule to block <script in the request parameter:

SecDefaultAction phase:2,deny,status:403,log,auditlog
SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "(?i:<script.*?>)" "phase:2,capture,t:none,t:htmlEntityDecode,t:compressWhiteSpace,t:lowercase,block,msg:'Cross-site Scripting (XSS) Attack',id:'101'"