Questioning PCI DSS 6.6... A Web Application Firewall Does Not Equal Security
I have performed a large number of Web Application Security Assessments over the years, and as a result, I have encountered a fairly large number of Web Application Firewalls.
It never ceases to amaze me how poorly many of these firewalls are configured. In many cases, I find that the web application firewall does very little to protect the client from anything, except the most basic of attacks.
One of my favorite web application vulnerabilities is Cross Site Scripting (XSS). For some strange reason, I still get a kick when a pop-up box appears in my web browser that says “XSS”.
Unfortunately, that is all XSS has become to many web application developers and network engineers… nothing more than a pop-up. This notion is due in part to the security community’s inability to communicate a vulnerability’s business impact to non-technical personnel.
Security Personnel's Inability to Speak to Non-Technical Personnel - (The Widget Breaks the Blurp and Crashes the Gloop! You Need to Invest Lots of Money Quickly!)
Many times, companies hire a security consultant to perform a Web Application Security Assessment on one of their main sites. The consultant runs a web application scanner, which finds XSS vulnerabilities.
In order to test for the vulnerability, the web application scanner uses a XSS payload that is easy to reproduce and normally results in some sort of pop-up in the web browser. This pop-up normally says something like “XSS” or “Hello World”.
The consultant provides the client with a list of parameters that are vulnerable to XSS along with the proof of concept code that the scanner used to identify the XSS vulnerability.
The client throws the vulnerable link in their browser, and as a result (horror of horrors), a pop-up that says “XSS” appears in the browser. The consultant never explains that this is just basic proof of concept code and that real world XSS attacks could result in logging keystrokes, stealing session cookies, or even the possibility of remote code execution on machines connecting to the vulnerable site (when linked with other vulnerabilities).
As a result, many companies that configure web application firewalls do not truly understand the web application attacks they are trying to prevent. Thus, in many cases, we have poorly coded web applications with poorly configured web application firewalls "protecting" them.
The ability to competently explain the findings from a Web Application Security Assessment is one of the many reasons it is important to have a reputable security consulting company perform Web Application Security Assessments.
This is true whether the Assessment is a White Box, Grey Box, or Black Box Web Application Security Assessment.
Blocking the Word "Script" (We are all Actors on the Stage of Life... Sorry, Wrong Script)
The first web application firewall misconception that drives me crazy is the belief that filtering out keywords that are commonly used in XSS attacks (or even worse XSS proof of concept code) will somehow stop XSS attacks.
Many times, the web application firewall has been configured to block requests containing the words “script” and/or “alert”. The word “script” is blocked due to the fact that the idea behind XSS is to get a hacker controlled script to execute in the victim’s web browser within the context of the vulnerable web application.
One way the attacker can do this is to insert script tags containing a script of the attacker’s choice into the underlying HTML markup when a user connects to the vulnerable site.
An example script the attacker could use is as follows:
< s c r i p t > a l e r t ( ‘ X S S ’ ) < / s c r i p t >
One of the problems with flagging on the word “script” in order to prevent XSS attacks is the fact that the attacker does not need to insert script tags into the underlying HTML, in order to successfully execute an XSS attack.
The attacker can use tags other than SCRIPT, such as IFRAME, BODY, or DIV tags, in order to embed a script into the underlying HTML. For example, an attacker could use any of the following tags to generate a pop-up that says “XSS”:
< i f r a m e s r c = " j a v a s c r & # x 0 9 ; i p t : a l e r t ( ' X S S ' ) " >
< b o d y o n l o a d = a l e r t ( ' X S S ' ) >
< d i v s t y l e = " x s s : e x p r e s s i o n ( a l e r t ( ' X S S ' ) ) " >
< a h r e f = " h t t p : / / t e s t . c o m " o n m o u s e o v e r = " a l e r t ( ' X S S ' ) " > t e s t < / a >
So we see that filtering out the word “script” is not going to prevent XSS attacks, but what about filtering out the word “alert”? There seems to be a misconception that somehow blocking requests with the word “alert” in them will somehow prevent successful XSS attacks.
This is largely due to the fact that most XSS proof of concept code uses the word “alert” in the example. I use “alert(‘XSS’)” in my examples because it is a small script that takes me less than a second to write.
The fact remains that these are just XSS examples. An attacker could create a malicious payload without using the word “alert”. Flagging on the word alert will not prevent any real XSS attacks!
Conclusion (A conclusion is simply the place where someone got tired of thinking)
It is important to understand what I am trying to say. I am not saying that blocking keywords that are associated with XSS is a bad thing. I am saying that when the blocking of keywords is used as the PRIMARY means of preventing XSS attacks, then the web application firewall could be doing very little to block real world attacks.
It is important that the people who are configuring web application firewalls are proficient with understanding web application vulnerabilities. This means that not only should web application developers attend annual secure coding practices training, but those who configure the web application firewalls should as well.
This will help those responsible for configuring web application firewalls to configure them correctly. So if blocking keywords is not the answer to an effective web application firewall configuration, could it be that blocking or encoding special characters like <, >, or “ is the answer?
This is something I will address in my next post.
Cross-posted from SecureState