Intercepting Filters
Most WAFs implement the
Intercepting Filter pattern or include one or more implementations in
their overall architecture. Filters are a series of independent modules
that you can chain together to perform processing before and after the
core processing of a requested resource (Web page, URL, script, etc.).
Filters do not have explicit dependencies on each other; this allows you
to add new filters without affecting existing filters. This modularity
makes filters reusable across applications. You can add filters to
applications at deployment when implemented as a Web server plug-in or
when activated dynamically within an application configuration file.
Filters are ideal
for performing centralized, repeatable tasks across requests and
responses that are loosely coupled with core application logic. They are
also good for security functions such as input validation,
request/response logging, and transforming outgoing responses. In the
next two sections, we’re going to look at two common filter
implementations: Web server plug-ins and application framework modules.
You can use both of them for runtime SQL injection protection. Figure 1 shows where each is executed as the HTTP request and response passes to/from the Web browser.
Web Server Filters
You can implement filters
as Web server modules/plug-ins, which extend the core request and
response handling application program interface (API) of the Web server
platform. Basically, requests and responses handled by the Web server
pass through a series of phases, and
modules can register for execution at each phase. Web server modules
permit customized handling of a request before the request reaches the
Web application and after it has generated a response. All of this
occurs independently of other Web server modules that might be
registered and independently of the Web application’s underlying logic.
This feature makes Web server modules a good implementation choice for
filters. Popular Web server platforms such as Apache, Netscape, and
Internet Information Server (IIS) all support this type of architecture.
Unfortunately, because each exposes its own API, you cannot leverage
the modules across Web server platforms.
A clear advantage of
Web server modules is that they are not bound to a particular Web
application framework or programming language. For example, IIS
plug-ins, called ISAPI filters, can be used to validate and monitor
requests bound for classic ASP and ASP.NET Web applications, as well as
transform their response content. When the Web server is configured to
use a connector (a filter that routes requests to the appropriate
resource handler) or in reverse proxy server mode, filters can be
leveraged to protect virtually any Web application (i.e., you can use
IIS ISAPI filters to protect J2EE, PHP, and ColdFusion Web
applications). Lastly, because filters are executed for every Web page
request, performance is critical. Web server filters are typically
implemented in a native programming language such as C or C++, which can
be very fast, but has the potential to introduce new classes of
vulnerabilities to consider, such as buffer overflows and format string
issues.
Web server modules are an
important component of runtime security because of the request and
response handling APIs they expose. This allows you to extend the
behavior of the Web server to meet your specific needs, such as writing a
filter for SQL injection protection. Luckily, you can use several
freely available Web server filter implementations for SQL injection
protection. We already discussed ModSecurity, an Apache API module which
offers considerable SQL injection protection. What follows is a brief
description of UrlScan and WebKnight, ISAPI filters that plug into the
IIS Web server platform and provide SQL injection protection:
UrlScan
In June 2008, Microsoft released Version 3.1 of UrlScan as an upgrade
to the 2.5 version originally released as part of the IIS Lock Down
Tool. Like its predecessor, 3.1 is a free ISAPI filter that blocks
certain malicious requests; however, this version is geared toward
application-level attacks—specifically, SQL injection, as it was
released in response to the mass SQL injection worms that began
infecting Web sites in early 2008. This new version supports creating
custom rules for blocking certain malicious requests; however, its
protection is limited to querystrings, headers, and cookies. You can
apply the rules to any Web resource hosted on the server, such as
classic ASP and ASP.NET resources. It also enhances the normal IIS
logging facilitates, supports a logging-only mode, and is configurable
from the urlscan.ini file.
Unfortunately, regular expressions are not supported and POST
data is not protected. These two limitations make UrlScan a
less-than-optimal solution for SQL injection protection. Because it is
easy to install, it could be useful for legacy applications where code
modifications are not an option and a quick band-aid solution is needed.
WebKnight
Like UrlScan, WebKnight is implemented as an IIS ISAPI filter that
blocks certain malicious requests. It matches all of the features
offered by UrlScan, and by far its biggest benefit over UrlScan is that
it can check POST
data for malicious input. It is highly configurable and comes with a
GUI, which makes it easier to configure than UrlScan. In fact, you can
import your UrlScan settings into WebKnight. Unfortunately, like
UrlScan, WebKnight does not support regular expressions and so is
limited to blacklist keyword validation. Additionally, POST
data protection requires that you set up WebKnight as a global filter,
which for IIS 6.0 Web servers means running in IIS 5.0 Isolation Mode.
WebKnight
is a better solution than UrlScan when it comes to SQL injection due to
its more comprehensive coverage of the request. It is also easy to
install, but its lack of support for regular expressions and a positive
security model make it more of a quick band-aid solution or an initial
defense mechanism against automated SQL injection worms.
You can download WebKnight at www.aqtronix.com.
Know Your Filter
Before using a filter to
protect your Web application from SQL injection, it’s important that
you understand how the filter works and the type of protection it
provides. Although filters are valuable runtime security tools, they can
introduce a false sense of security if you do not completely understand
their behavior and security model. Microsoft’s UrlScan 3.1 is a good
example of this, as it provides only querystring, header, and cookie
protection. Pages with POST parameters vulnerable to SQL injection will be left exposed to exploitation.
|
Application Filters
You
also can implement filters in the Web application’s programming
language or framework. The architecture is similar to that of Web server
plug-ins: Modular code executes as requests and responses pass through a
series of phases. You can use the ASP.NET System. Web.IHttpModule interface and the javax.servlet.Filter
interface to implement the filter pattern. You can then add them to an
application without code changes and activate them declaratively in the
application configuration file. Figure 8 shows an example code snippet of the doFilter method of a custom J2EE Filter
class. This method is called for each request/ response pair due to a
request for a J2EE Web resource ( JSP file, servlet, etc.).
Figure 8. Code Snippet of a Custom J2EE Filter Class
public class SqlInjDetectionFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
chain filterChain) throws IOException, ServletException
{
// Check request data for malicious characters
doDetectSqlI(req, res);
// Call next filter in the chain
chain.doFilter(servletRequest, servletResponse);
}
}
|
In terms of
runtime protection, application filters are really nice because they can
be developed independent of the application, deployed as a stand-alone
.dll or .jar file, and turned on immediately. This means this solution
can be deployed more quickly in certain organizations because Web server
configuration changes are not required (in many organizations,
application developers do not have access to the Web servers and so must
coordinate with the Web server team to make the configuration changes
associated with a Web server filter). Because these filters are
implemented in the same programming language as the application, they
can extend or closely wrap existing application behavior. For this same
reason, their utility is limited to applications built on the same
framework (refer to the Tools and Traps sidebar, “Protecting Web
Applications with ASP.NET and IIS,” for information on how you can
overcome this limitation).
Similar to Web server
filters, application filters allow you to add security features, such as
malicious request detection, prevention, and logging, to vulnerable Web
applications. Because they can be written in feature-rich
object-oriented languages such as Java and C#, they are usually less
complex to code and do not introduce new vulnerability classes such as
buffer overflows. OWASP Stinger and Secure Parameter Filter (SPF) are
free application filters that you can use to detect and block SQL injection attacks.
Protecting Web Applications with ASP.NET and IIS
Web applications that are
not built on the .NET Framework, but run on IIS (PHP, classic ASP, Perl,
etc.), can be processed by ASP.NET code modules by mapping their file
type (.php, .asp, .pl, etc.) to an ASP.NET ISAPI dynamic link library
(DLL). You can configure this under the application’s configuration in
IIS with the Application Configuration | Mappings
tab. In this scenario, an ASP.NET HttpModule that performs input
validation and logging can now be leveraged on non-ASP.NET Web
applications. However, there are limitations on what you can do to the
request and response, especially in the area of response transformation.
The IIS 7.0 ASP.NET
Integrated Mode enhances this capability further by combining the
ASP.NET request pipeline with the IIS core request pipeline.
Essentially, you can plug ASP.NET HttpModules into IIS and have control
over the entire request and response that in previous versions of IIS
was possible only with an ISAPI filter. This gives HttpModules the
capability to perform comprehensive processing of requests and
responses, and permits a module such as SPF to provide non-editable
input protection to non-ASP.NET Web applications through transformation
of response content. For more information on the type of protection SPF
provides, refer to “Non-Editable versus Editable Input Protection.”
|
Implementing the Filter Pattern in Scripted Languages
For Web scripting
languages, the filter pattern can be more difficult to implement.
Technologies such as PHP and classic ASP don’t provide built-in
interfaces for hooking into request/ response handling before/after page
execution. You could use a Web server filter or even an application
filter (refer to the Tools and Traps sidebar, “Protecting Web
Applications with ASP. NET and IIS,” for more details) to protect a
vulnerable classic ASP application; however, this requires
administrative privileges on the Web server to make configuration
changes, which may not always be the case or may not be convenient.
Additionally, you may not want to modify the code for reasons discussed
at the start of “Using Runtime Protection.”
For PHP Web applications, you can leverage the auto_ prepend_ file and auto_append_ file
configuration directives in the php.ini file. These directives point to
PHP files that will be executed before and after the execution of every
PHP script that is requested. The added-in logic would loop through the
various HTTP request collections (querystring, POST, cookies, headers, etc.) and validate and/or log as necessary.
An alternative for both PHP and classic ASP applications is to use include files.
This requires code modification in the form of adding include
directives on every application page. Similarly, the included logic
would loop through the various HTTP request collections and validate
and/or log as necessary.
Filtering Web Service Messages
The intercepting filter
pattern is also easy to apply to XML Web Services with custom input and
output filters. An input filter could perform validation of method
parameters and log SQL injection attempts. You also could use an output
filter to suppress error details, such as those that often leak out in
the faultstring of the Soap Fault message. The .NET Web Services and
Apache Axis platforms provide mechanisms for filtering inbound and
outbound messages.
ModSecurity can also handle inbound XML messages to perform validation and logging with the XML TARGET. Validation can be performed with XPATH
queries or against a schema or document type definition (DTD) file.
Commercial XML firewalls can also be considered, although they are
typically network appliances and likely overkill if you are just looking
for SQL injection protection.
Non-Editable versus Editable Input Protection
Almost every
filter implementation employs blacklist protection, whereas whitelist
validation, which is much more powerful and effective against SQL
injection, is less prevalent and often complex to configure. This is
likely because defining an exact match (i.e., whitelist) for every
request parameter is a daunting task, even if a learning mode is
available. This is especially true for inputs that except free-form
text, such as textboxes.
Another input
validation strategy to consider is classifying application inputs as
editable and non-editable, and locking down the non-editable inputs so
that they cannot be manipulated. Non-editable inputs are those that end
users do not need to modify directly—hidden form fields, URIs and
querystring parameters, cookies, etc. The theory behind the strategy is
that the application should permit users to perform only those actions
that the user interface has presented to them. The idea is to leverage
HTTP responses at runtime to identify all legitimate requests (forms and
links), collect the state of each possible request, and then validate
subsequent requests against the stored state information. For many
applications, non-editable inputs are the majority of input accepted by
an application. Therefore, if you can lock these down automatically at
runtime, you can then focus your efforts on comprehensively validating the editable inputs, which is usually a much more manageable task.
Examples of
technologies that implement this strategy are HTTP Data Integrity
Validator (HDIV) and SPF. You can use HDIV to protect most J2EE Web
applications that follow the Model-View-Controller (MVC) pattern and you
can download it at www.hdiv.org.
You can use SPF to protect ASP.NET Web applications when run on IIS
6.0; however, it can be leveraged to protect virtually any Web
application when run on IIS 7.0. Refer to the Tools and Traps sidebar,
“Protecting Web Applications with ASP.NET and IIS,” for more
information. You can download SPF at www.gdssecurity.com/l/spf/.
URL/Page-Level Strategies
Let’s look at some other techniques for virtual-patching a vulnerable URL or page without changing the source code.
Page Overriding
If a page is vulnerable
and needs replacing, you can create a replacement page or class that is
substituted at runtime. The substitution is accomplished with
configuration in the Web application’s configuration file. In ASP.NET
applications, you can use HTTP handlers to accomplish this task.
Figure 9
shows a custom HTTP handler configured to handle requests to
PageVulnToSqlI.aspx instead of the vulnerable page itself. The
substituted handler class implements the logic of the original page in a
secure manner. This could include stringent validation of request
parameters and the use of secure data access objects.
Figure 9. Configuring an HTTP Handler in web.config
<httpHandlers>
<add verb="*"
path="PageVulnToSqlI.aspx"
type="Chapter9.Examples.SecureAspxHandler, Subclass"
validate="false" />
</httpHandlers>
|
You can use a similar
approach in the deployment descriptor of a J2EE Web application. You can
map the vulnerable URL to a servlet that handles the request in a
secure manner, as shown in Figure 10.
Figure 10. Configuring a Substitute Servlet in web.xml
<servlet>
<servlet-name>SecureServlet</servlet-name>
<servlet-class>chapter9.examples.SecureServletClass</servlet-class>
</servlet>
..
<servlet-mapping>
<!--<servlet-name>ServletVulnToSqli</servlet-name>-->
<servlet-name>SecureServlet</servlet-name>
<url-pattern>/ServletVulnToSqli</url-pattern>
</servlet-mapping>
|
URL Rewriting
A
somewhat similar technique to page overriding is URL rewriting. You can
configure the Web server or application framework to take requests that
are made to a vulnerable page or URL and redirect them to an
alternative version of the page. This new version of the page would
implement the logic of the original page in a secure manner. The
redirection should be performed server-side so that it remains seamless
to the client. There are a number of ways to accomplish this depending
on the Web server and application platform. The Apache module mod_rewrite and the .NET Framework urlMappings element are two examples.
Resource Proxying/Wrapping
You can combine resource
proxying/wrapping with either page overriding or URL rewriting to
minimize the amount of custom coding needed in the replacement page.
When the replacement page handles the rewritten request, it would
iterate through the request parameters (querystring, POST,
cookies, etc.) and perform the required validations. If the request is
deemed safe, the request would be permitted to pass on to the vulnerable
page via an internal server request. The vulnerable page would then
handle the input and perform whatever rendering is needed. Passing input
to the vulnerable page in this manner is okay because the replacement
page already performed the necessary validation. Essentially, the
replacement page wraps the vulnerable page, but does not require
duplication of logic.
Aspect-Oriented Programming (AOP)
Aspect-oriented
programming is a technique for building common, reusable routines that
can be applied applicationwide. During development this facilitates
separation of core application logic and common, repeatable tasks (input
validation, logging, error handling, etc.).
At
runtime, you can use AOP to hot-patch applications that are vulnerable
to SQL injection, or embed intrusion detection and audit logging
capabilities directly into an application without modifying the
underlying source code. The centralization of security logic is similar
to the intercepting filter previously discussed, except the benefits of
AOP can extend well beyond the Web tier. You can apply security aspects
to data access classes, thick client applications, and middle-tier
components, such as Enterprise JavaBeans (EJBs). For example, you could
implement checks for insecure dynamic SQL libraries (e.g., executeQuery( )),
prevent the query from executing, and log the offending call for
follow-up remediation efforts. There are a number of AOP
implementations, but some of the more common ones are AspectJ, Spring
AOP, and Aspect.NET.
Application Intrusion Detection Systems (IDSs)
You could use traditional
network-based IDSs to detect SQL injection attacks; however, these IDSs
are often not optimal, as they are far removed from the application and
Web server. However, if you already have one of these running on your
network you could still leverage it for an initial line of defense.
As mentioned previously, a
WAF can serve as a very good IDS because it operates at the application
layer and can be finely tuned for the specific application being
protected. Most WAFs come with a passive mode and with alerting
capabilities. In many production application environments, using a
security filter or WAF in this capacity is preferred. You can use them
to detect attacks and alert administrators who can then decide what
should be done about the vulnerability—for example, perhaps enabling
blocking of malicious requests for the specific page/parameter
combination or applying a virtual patch.
Another option is an embedded solution such as PHPIDS (http://php-ids.org/).
PHPIDS does not filter or sanitize input, but rather detects attacks
and takes action based on its configuration. This could range from
simple logging to sending out an emergency e-mail to the development
team, displaying a warning message for the attacker or even ending the
user’s session.
Database Firewall
The
last runtime protection technique we’ll cover is the database firewall,
which is essentially a proxy server that sits between the application
and the database. The application connects to the database firewall and
sends the query as though it were normally connecting to the database.
The database firewall analyzes the intended query and passes it on to
the database server for execution if deemed safe. Alternatively, it can
prevent the query from being run if malicious. It can also serve as an
application-level IDS for malicious database activity by monitoring
connections in passive mode and altering administrators of suspicious
behavior. In terms of SQL injection, database firewalls could
potentially be just as effective if not more
so than WAFs. Consider that the queries the Web application sends to
the database are, for the most part, a known quantity of commands, and
their structure is known as well. You can leverage this information to
configure a highly tuned set of rules that takes appropriate action
(log, block, etc.) against unusual or malicious queries before ever
hitting the database. One of the hardest problems with locking down
input in a WAF is that malicious users can send in any combination of
requests to the Web server. An example open source implementation is
GreenSQL, which you can download at www.greensql.net.