Edsger Dijkstra once famously stated, “Testing shows the presence, not the absence of bugs.” Accordingly, even well-tested web applications written by the most security conscious developers are still likely to contain security flaws. In light of this reality, defense-in-depth is a wise strategy. A common means of defending web applications in production is through the use of a web application firewall (WAF) which monitors user input to an application for suspicious or problematic behavior. For instance, a WAF may examine incoming user input for the telltale signs of SQL injection (e.g., any of the variations on the classic pattern
' OR 1=1; --'). If it determines input to be malicious, it will drop the request thus preventing an attack on the application. However, there is new defensive technology called runtime application self-protection (RASP) which may offer a more effective means of mitigating unidentified vulnerabilities.
The pattern matching approach employed by application firewalls is not without its downsides. WAFs are notoriously onerous to deploy and maintain. During deployment, they must be extensively tuned to properly support the application they are protecting, and they must be re-tuned on a regular basis to account for changes in the application as well as emerging threats and attacks. Often, the effectiveness of a WAF degrades over time as this re-tuning is neglected. Further, because WAFs sit in front of the applications they defend, they have no context in which to evaluate user input leading to a potentially high rate of false positives. Compounding these issues, WAFs are usually configured to fail open under heavy load (i.e., turn off) to avoid rendering the defended application unreachable due to the overhead incurred by the WAF itself. An attacker can exploit this configuration via a DDoS attack to remotely disable a WAF allowing unfiltered access to the application and its inputs. WAFs are therefore a brittle means of defending a web application.
In response to these shortcomings, several companies (including big names like Hewlett-Packard and various startups) are developing and licensing a new approach to web application defense called runtime application self-protection (RASP). A RASP, unlike a WAF, can make decisions about the defense of an application in the context of the executing application. This is because a RASP, as the name suggests, instruments the language runtime executing the application. So rather than simply pattern matching incoming traffic before the application even receives the input, a RASP examines user input in the execution context of the request being evaluated. If a RASP determines input to be malicious, it will prevent the execution of the targeted function to prevent exploitation. This has two distinct advantages. Namely false positive rates are reduced and logging is greatly improved.
Since a WAF has to filter input without context, it cannot determine if malicious input would actually result in a successful attack or if an attacker is probing for vulnerabilities. This is not the case with RASPs. By the time a RASP is deciding if input is malicious, the application has already performed input validation and sanitization. This enables one of the most notable advantages of RASPs over firewalls: the identification of potential flaws. If a RASP prevents a function invocation because it believes input to be malicious this implies the application failed to properly sanitize input in that case. The RASP can then log the attempted exploitation along with the file and line number of the potential vulnerability.
However, RASPs are not without their own disadvantages. Among the most significant arises from the main feature of RASPs, the instrumentation of language runtimes; a RASP is inherently tied to a specific language. This restrains your choice of product based on the language in which your application is written. This could even render the consideration moot if no RASP exists for the language your application is written in. What’s more, the methodologies and heuristics employed by a RASP are are often considered to be proprietary information by the software vendor. This represents a trade off between RASPs and firewalls. While the tuning of WAFs maybe difficult, it does provide a great deal of control. The price of a much easier setup is that RASPs require ceding a fair amount of control to a third-party vendor. There is also the added factor that RASPs directly alter the behaviors and performance characteristics of language runtimes in ways that may not be fully understood by anyone not involved in the RASP’s development. A RASP may even introduce new vulnerabilities to an application stack since a RASP, like any other piece of software, is subject to flaws and bugs.
A problem common to both solutions is they can induce a sense of complacency. Using one or both in lieu of defensive coding practices and iterative testing is not a sound strategy. Both approaches, when properly implemented and maintained, provide an additional layer of protection, but both also employ, at their core, a heuristic approach to defense and are thus imperfect. Application firewalls and RASPs are intended as reinforcements to proper defensive practices, not substitutes for them.