Intercepting Filter

The Intercepting Filter pattern may be used in instances where there is the need to execute logic before and after the main processing of a request (pre and postprocessing). The logic resides in Filter objects and typically consist of code that is common across multiple requests. The Servlet 2.3 Specification provides a mechanism for building filters and chaining of Filters through configuration. A FilterManager controls the execution of a number of loosely-coupled Filters (referred to as a FilterChain), each of which performs a specific action. This Standard Filter Strategy can also be replaced by a Custom Filter Strategy which replaces the Servlet Specification’s object wrapping with a custom implementation.

Analysis

Avoid

Relying Only on a Blacklist Validation Filter

Developers often use blacklists in Filters as their only line of defense against input attacks such as Cross Site Scripting (XSS). Attackers constantly circumvent blacklists because of errors in canonicalization and character encoding. In order to sufficiently protect applications, do not rely on a blacklist validation filter as the sole means of protection; also validate input with strict whitelists on all input and/or encode data at every sink.

Output Encoding in Filter

Encoding data before forwarding requests to the Target is too early because the data is too far from the sink point and may actually end up in several sink points, each requiring a different form of encoding. For instance, suppose an application uses a client-supplied e-mail address in a Structured Query Language (SQL) query, a Lightweight Directory Access Protocol (LDAP) lookup, and within a Hyper Text Markup Language (HTML) page. SQL, LDAP, and HTML are all different sinks and each requires a unique form of encoding. It may be impossible to encode input at the Filter for all three sink types without breaking functionality. On the other hand, performing encoding after the Target returns data is too late since data will have already reached the sink by the time it reaches the Filter.

Overly Generous Whitelist Validation

While attempting to implement whitelist validation, developers often allow a large range of characters that may include potentially malicious characters. For example, some developers will allow all printable ASCII characters which contain malicious XSS and SQL injection characters such as less than signs and semi-colons. If your whitelists are not sufficiently restrictive, perform additional encoding at each data sink.

XML Denial of Service

If you use Intercepting Filter to preprocess XML messages, then remember that attackers may try many different Denial of Service (DOS) attacks on XML parsers and validators. Ensure either the web server, application server, or the first Filter on the chain performs a sanity check on the size of the XML message priortoXML parsing or validation to prevent DOS conditions.

Logging Arbitrary HTTP Parameters

A common cross-cutting application security concern is logging and monitoring of user actions. Although an Intercepting Filter is ideally situated to log incoming requests, avoid logging entire HTTP requests. HTTP requests contain user-supplied parameters which often include confidential data such as passwords, credit card numbers and personally identifiable information (PII) such as an address. Logging confidential data or PII may be in violation of privacy and/or security regulations.

Use to Implement

Input Validation

Use an Intercepting Filter to implement security input validation consistently across all presentation tier pages including both Servlets and JSPs. The Filter’s position between the client and the front/application controllers make it an ideal location for a blacklist against all input. Ideally, developers should always employ whitelist validation rather than blacklist validation; however, in practice developers often select blacklist validation due to the difficulty in creating whitelists. In cases where blacklist validation is used, ensure that additional encoding is performed at each data sink (e.g. HTML and JavaScript encoding).

Page-Level Authorization

Use an Intercepting Filter to examine requests from the client to ensure that a user is authorized to access a particular page. Centralizing authorization checks removes the burden of including explicit page-level authorization deeper in the application. The Spring Security framework employs an Intercepting Filter for authorization.

Remember that page-level authorization is only one component of a complete authorization scheme. Perform authorization at the command level if you use Command objects, the parameter level such as HTTP request parameters, and at the business logic level such as Business Delegate or Session Façade. Remember to propagate user access control information such as users’ roles to other design layers like the Application Controller. The OWASP Enterprise Security Application Programming Interface (ESAPI) uses ThreadLocal objects to maintain user authorization data throughout the life of a thread.

Session Management

Session management is usually one of the first security controls that an application applies to a request. Aside from container-managed session management controls such as idle timeout and invalidation, some applications implement controls such as fixed session timeout, session rotation and session-IP correlation through proprietary code. Use an Intercepting Filter to apply the additional session management controls before each request is processed.

Invalidating the current session token and assigning a new session token after authentication is a common defense against session fixation attacks. This control can also be handled in an Intercepting Filter specifically configured to intercept authentication requests. You may alternatively use a generic session management Filter that intercepts all requests, and then use conditional logic to check, specifically, for authentication requests in order to apply a defense against session fixation attacks. Be aware, however, that using a generic Filter introduces maintenance overhead when you implement new authentication paths.

Audit Logging

Since Intercepting Filters are often designed to intercept all requests, they are ideally situated to perform logging of user actions for auditing purposes. Consider implementing a Filter that intercepts all requests and logs information such as:

Username for authenticated requests

Timestamp of request

Resource requested

Response type such as success, error, etc.

The logging filter should be configured as the first Filter in the chain in order to log all requests irrespective of any errors that may occur in Filters further down the chain. Never log confidential or PII data.

Front Controller

Processing a request typically consists of a number of request handling activities such as protocol handling, navigation and routing, core processing, and dispatch as well as view processingvii. A controller provides a place for centralizing this common logic performed for each request. Typically implemented as a Servlet, the Front Controller can perform this common logic and further delegate the action management (servicing the request) and view management (dispatching a view for user output) activities to an Application Controller. This pattern provides centralization of request control logic and partitioning of an application between control and processing.

Analysis

Avoid

Physical Resource Mapping

The Physical Resource Mapping strategy maps user-supplied parameters directly to physical resources such as files residing on the server. Attackers often take advantage of this strategy to gain illicit access to resources. In a directory traversal exploit, for example, clients supply the server with the physical location of a file such as “file=statement_060609.pdf”. Attackers attempt to access other files on the server by supplying malicious parameters such as “file=../../../../../etc/password”. If the application blindly accepts and opens any user-supplied filename then the attacker may have access to a whole array of sensitive files, including properties and configuration files that often contain hard-coded passwords.

Developers sometimes mitigate directory traversal attacks by checking for the presence of a specific prefix or suffix, such as verifying that the file parameter begins with “statement” and ends with “.pdf”. A crafty attacker can take advantage of null character injection and enter “file=statement_060609.pdf/../../../../etc/password%00.pdf”. Java will see that the resource beings with “statement” and ends with “.pdf” whereas the operating system may actually drop all remaining characters after the %00 null terminator and open the password file.

As a rule, avoid using the Physical Resource Mapping strategy altogether. If you must use this strategy, ensure that the application operates in a sandboxed environment with the Java Security Manager and/or employs sufficient operating system controls to protect resources from unauthorized access.

Invoking Commands Without Sufficient Authorization

In the Command and Controller strategy, users supply a Command object which the Application Controller subsequently handles by invoking an action. Developers who rely on client-side controls and page-level access control often forget to check if the user is actually allowed to invoke a given Command.

Attackers take advantage of this vulnerability by simply modifying a parameter. A common example is a Create Read Update Delete (CRUD) transaction, such as http://siteurl/controller?command=viewUser&userName=jsmith. An attacker can simply modify “viewUser” to “deleteUser”. Often developers assume that if clients cannot see a link to “deleteUser” on a web page then they will not be able to invoke the “deleteUser” command. We like to call this GUI-based Authorization and it is a surprisingly common vulnerability in web applications.

Ensure that clients are actually allowed to invoke the supplied command by performing an authorization check on the application server. Provide the Application Controller sufficient data about the current user to perform the authorization check, such as roles and username. Consider using a Context object to store user data.

Unhandled Mappings in the Multiplexed Resource Mapping Strategy

The Multiplexed Resource Mapping strategy maps sets of logical requests to physical resources. For example, all requests that end with a “.ctrl” suffix are handled by a Controller object. Often developers forget to account for non-existent mappings, such as suffixes not associated with specific handlers.

Create a default Controller for non-existent mappings. Ensure the Controller simply provides a generic error message; relying on application server defaults often leads to propagation of detailed error messages and sometimes even reflected XSS in the error message (e.g. “The resource <script>alert(‘xss’)</script>.pdf could not be found”).

Logging of Arbitrary HTTP Parameters

A common cross-cutting application security concern is logging and monitoring of user actions. Although a Front Controller is ideally situated to log incoming requests, avoid logging entire HTTP requests. HTTP requests contain user-supplied parameters which often include confidential data such as passwords and credit card numbers and personally identifiable information (PII) such as an address. Logging confidential data or PII may be in violation of privacy and/or security regulations.

Duplicating Common Logic Across Multiple Front Controllers

If you use multiple Front Controllers for different types of requests, be sure to use the Base Front strategy to centralize security controls common to all requests. Duplicating cross-cutting security concerns such as authentication or session management checks in multiple Front Controllers may decrease maintainability. In addition, the inconsistent implementation of security checks may result in difficult-to-find security holes for specific use cases. If you use the BaseFront strategy to encapsulate cross-cutting security controls, then declare all security check methods as final in order to prevent method overriding and potentially skipping security checks in subclasses. The risk of overriding security checks increases with the size of the development team.

Use to Implement

Session management is usually one of the first security controls that an application applies to a request. Aside from container-managed session management controls such as idle timeout and invalidation, some applications implement controls such as fixed session timeout, session rotation, and session-IP correlation through proprietary code. Use a Front Controller to apply the additional session management controls before each request is processed.

Invalidating the current session token and assigning a new session token after authentication is a common defense against session fixation attacks. This control can also be handled by Front Controller .

Audit Logging

Since Front Controllers are often designed to intercept all requests, they are ideally situated to perform logging of user actions for auditing purposes. Consider logging request information such as:

Username for authenticated requests

Timestamp of request

Resource requested

Response type such as success, error, etc.

Never log confidential or PII data.

Context Object

In a multi-tiered applications, one tier may retrieve data from an interface using a specific protocol and then pass this data to another tier to be used for processing or as input into decision logic. In order to reduce the dependency of the inner tiers on any specific protocol, the protocol-specific details of the data can be removed and the data populated into a ContextObject which can be shared between tiers. Examples of such data include HTTP parameters, application configuration values, or security data such as the user login information, defined by the Request Context, Configuration Context, and Security Context strategies, respectively. By removing the protocol-specific details from the input, the Context Object pattern significantly reduces the effort required to adapt code to a change in the application’s interfaces.

Analysis

Avoid

Context Object Auto-Population Strategy

The Context Object Auto-Population strategy uses client-supplied parameters to populate the variables in a Context object. Rather than using a logical mapping to match parameters with Context variables, the Context Object Auto-Population strategy automatically matches Context variable names with parameter names. In some cases, developers maintain two types of variables within a Context object: client-supplied and server supplied. An e-commerce application, for example, might have a ShoppingCartContext object with client-supplied product ID and quantity variables and a price variable derived from a server-side database query. If a client supplies a request such as “http://siteurl/controller?command=purchase&prodID=43quantity=2” then the Context Object Auto-Population strategy will automatically set the ShoppingCartContext.prodId=43 and ShoppingCartContext.quantity=2. What if the user appends “&price=0.01” to the original query? The strategy automatically sets the ShoppingCarContext.price=0.01 even though the price value should not be client controlled. Ryan Berg and Dinis Cruz and of Ounce labs documented this as a vulnerability in the Spring Model View Controller (MVC) framework.

Avoid using the Context Object Auto-Population strategy wherever possible. If you must use this strategy, ensure that the user is actually allowed to supply the variables to the context object by performing explicit authorization checks.

Assuming Security Context Reflects All Security Concerns

The Security Context strategy should more precisely be called an Access Control Context strategy. Developers often assume that security is comprised entirely of authentication, authorization and encryption. This line of thinking often leads developers to believe that using the Secure Socket Layer (SSL) with user authentication and authorization is sufficient for creating a secure web application.

Also remember that fine-grained authorization decisions may be made further downstream in the application architecture, such as at the Business Delegate. Consider propagating roles, permissions, and other relevant authorization information via the Context object.

Use to Implement

Whitelist Input Validation

The Request Context Validation strategy uses the RequestContext object to perform validation on client-supplied values. The Core J2EE Patterns book provides examples for form and business logic level validation, such as verifying the correct number of digits in a credit card. Use the same mechanism to perform security input validation with regular expressions. Unlike Intercepting Filters, RequestContexts encapsulate enough context data to perform whitelist validation. Many developers employ this strategy in Apache Struts applications by opting to use the Apache Commons Validator plugin for security input validation.

In several real-world implementations of Request Context Validation, the RequestContext only encapsulates HTTP parameters. Remember that malicious user-supplied input can come from a variety of other sources: cookies, URI paths, and other HTTP headers. If you do use the Request Context Validation strategy for security input validation then provide mechanisms for security input validation on other forms of input. For example, use an Intercepting Filter to validate cookie data.

Flagging Tainted Variables

Conceptually, Context objects form the last layer where applications can differentiate between untrusted user-supplied data and trusted system-supplied data. For instance, a shopping cart Context object might contain a user-supplied shipping address and a database-supplied product name. Generally speaking, objects logically downstream from the Context object cannot distinguish user-supplied data from system-supplied data. If you encode data at sink points and you want to minimize performance impact by encoding only user-supplied data (as opposed to system generated data), then consider adding an “isTainted” flag for each variable in the Context class. Set “isTainted” to true if the variable is user supplied or derived from another user supplied value. Set “isTainted” to false if the variable is computer generated and can be trusted. Store the instance variable and “isTainted” booleans as key/value pairs in a collection with efficient lookups (such as a WeakHashMap). Downstream in the application, simply check if a variable is tainted (originates from user-supplied input) prior to deciding to encode it at sink points. For instance, you might HTML, JavaScript, or Cascading Stylesheet (CSS) encode all tainted data that you print to stream in a Servlet while leaving untainted data as is.

Application Controller

While the Front Controller pattern stresses centralization of logic common to all incoming requests, the conditional logic related to mapping each request to a command and view set can be further separated. The FrontController performs all generic request processing and delegates the conditional logic to an ApplicationController. The ApplicationController can then decide, based on the request, which command should service the request and which view to dispatch. The ApplicationController can be extended to include new use cases through a map holding references to the Command and View for each transaction. The Application Controller pattern is central to the Apache Struts model view controller framework.

Analysis

Avoid

Unauthorized Commands

In the Command Handler strategy, users supply a Command object which the ApplicationController subsequently handles by invoking an action. Developers who rely on client-side controls and page-level access control often forget to check if the user should actually be allowed to invoke a given Command.

Attackers take advantage of this vulnerability by simply modifying a parameter. A common example is a Create Read Update Delete (CRUD) transaction, such as http://siteurl/controller?command=viewUser&userName=jsmith. An attacker can simply modify “viewUser” to “deleteUser”. Often developers assume that if clients cannot see a link to “deleteUser” on a web page then they will not be able to invoke the “deleteUser” command. We call this vulnerability GUI-based Authorization and it is a surprisingly common in web applications.

Ensure that clients are actually allowed to invoke the supplied command by performing an authorization check on the application server. Provide the ApplicationController sufficient data about the current user to perform the authorization check, such as roles and username. Consider using a Context object to store user data.

Unhandled Commands

Create a default response page for non-existent commands. Relying on application server defaults often leads to propagation of detailed error messages and sometimes even reflected XSS in the error message (e.g. “The resource <script>alert(‘xss’)</script>.pdf could not be found”).

If you use Application Controller with XML messages then remember that attackers may try Denial of Service (DOS) attacks on XML parsers and validators. Ensure either the web server, application server, or an Intercepting Filter performs a sanity check on the size of the XML message priortoXML parsing or validation to prevent DOS conditions.

Disclosure of Information in SOAP Faults

One of the most common information disclosure vulnerabilities in web services is when error messages disclose full stack trace information and/or other internal details. Stack traces are often embedded in SOAP faults by default. Turn this feature off and return generic error messages to clients.

Publishing WSDL Files

Web Services Description Language (WSDL) files provide details on how to access web services and are very useful to attackers. Many SOAP frameworks publish the WSDL by default (e.g. http://url/path?WSDL). Turn this feature off.

Use to Implement

Synchronization Token as Anti-CSRF Mechanism

Synchronizer tokens are random numbers designed to detect duplicate web page requests. Use cryptographically strong random synchronized tokens to help prevent anti-Cross Site Request Forgery (CSRF). Remember, however, that CSRF tokens can be defeated if an attacker can successfully launch a Cross Site Scripting (XSS) attack on the application to programmatically parse and read the synchronization token.

Page-Level Authorization

If not already done using an Intercepting Filter, use the Application Controller to examine client requests to ensure that only authorized users access a particular page. Centralizing authorization checks removes the burden of including explicit page-level authorization deeper in the application.

Remember that page-level authorization is only one component to a complete authorization scheme. Perform authorization at the command level if you use Command objects, the parameter level such as HTTP request parameters, and at the business logic level such as Business Delegate or Session Façade. Remember to propagate user access control information such as users’ roles to other design layers. The OWASP Enterprise Security Application Programming Interface (ESAPI) uses ThreadLocal objects to maintain user authorization data throughout the life of a thread.

View Helper

View processing occurs with each request and typically consists of two major activities: processing and preparation of the data required by the view, and creating a view based on a template using data prepared during the first activity. These two components, often termed as Model and View, can be separated by using the View Helper pattern. Using this pattern, a view only contains the formatting logic either using the Template-Based View strategy such as a JSP or Controller-Based View Strategy using Servlets and XSLT transformations. The View then makes use of Helper objects that both retrieve data from the PresentationModel and encapsulate processing logic to format data for the View. JavaBean Helper and Custom Tag Helper are two popular strategies which use different data types (JavaBeans and custom view tags respectively) for encapsulating the model components.

Analysis

Avoid

XSLT and XPath Vulnerabilities

Some developers elect to use Xml Stylesheet Language Transforms (XSLTs) within their Helper objects. Avoid XSLT and related XPath vulnerabilities by performing strict whitelist input validation or XML encoding on any user-supplied data used in view generation.

Unencoded User Supplied Data

Many JEE developers use standard and third party tag libraries extensively. Libraries such as Java Server pages Tag Libraries (JSTL) and Java Server Faces (JSF) simplify development by encapsulating view building logic and hiding difficult-to-maintain scriptlet code. Some tags automatically perform HTML encoding on common special characters. The “c:out” and “$(fn:escapeXml(variable))” Expression Language (EL) tags in JSTL automatically HTML encode potentially dangerous less-than, greater-than, ampersand, and apostrophe characters. Encoding a small subset of potentially malicious characters significantly reduces the risk of common Cross Site Scripting (XSS) attacks in web applications but may still leave other less-common malicious characters such as percentage signs unencoded. Many other tags do not perform any HTML encoding. Most do not perform any encoding for other sink types, such as JavaScript or Cascading Style Sheets (CSS).

Assume tag libraries do not perform output encoding unless you have specific evidence to the contrary. Wherever possible, wrap existing tag libraries with custom tags that perform output encoding. If you cannot use custom tags then manually encode user supplied data prior to embedding it in a tag.

Composite View

Applications often contain common View components, both from layout and content perspectives, across multiple Views in an application. These common components can be modularized by using the Composite View pattern which allows for a View to be built from modular, atomic components. Examples of modular components which can be reused are page headers, footers, and common tables. A CompositeView makes use of a ViewManager to assemble multiple views. A CompositeView can be assembled by JavaBeans, standard JSP tags such as <jsp:include>, or custom tags, using the JavaBean View Management, Standard Tag View Management, or Custom Tag View Management strategies respectively.

One of the most common web applications vulnerabilities is weak functional authorization. Developers sometimes use user role data to dynamically generate views. In the Core J2EE Pattern books the authors refer to these dynamic views as “Role-based content”. Role-based content prevents unauthorized users from viewing content but does not prevent unauthorized users from invoking Servlets and Java Server Pages (JSPs). For example, imagine a JEE accounting application with two JSPs – accounting_functions.jsp which is the main accounting page and gl.jsp representing the general ledger. In order to restrict access to the general ledger, developers include the following content in accounts.jsp:

The code snippet above restricts the content in gl.jsp to users in the accountant role. Remember, however, that a user can simply access gl.jsp directly – a flaw that can be even more devastating if invoking gl.jsp with parameters causes a transaction to run such as posting a debit or credit.

Service to Worker

Applications commonly dispatch a View based exclusively on the results of request processing. In this the Service to Worker pattern, the Controller (either FrontController or ApplicationController) performs business logic and, based on the result of that logic, creates a View and invokes its logic. Service to Worker is different from Dispatcher View because in the latter the View logic is invoked before thebusiness logic is invoked.

Analysis

Avoid

Dispatching Error Pages Without a Default Error Handler

In Service to Worker, an ApplicationController manages the flow of web pages. When an application encounters an error, the ApplicationController typically determines which error page to dispatch. The Core J2EE Patterns book uses the following line of code to determine which error page to forward the user to:

next= ApplicationResources.getInstance().getErrorPage(e);

Many developers use the approach of mapping exceptions to particular error pages, but do not account for a default error page. As applications evolve, the job of creating a friendly error page for every exception type becomes increasingly difficult. In many applications the ApplicationController will simply dump a stack trace or even redisplay the client’s request back to them. Avoid both scenarios by providing a default generic error page. In Java EE you can implement default error handling through web.xml configuration.

Dispatcher View

In instances where there is a limited amount or no business processing required prior to generating a response, control can be passed to the View directly from the ApplicationController. The ApplicationController performs general control logic and is only responsible for mapping the request to a corresponding View. Dispatcher View pattern is typically used in situations where the response is entirely static or the response is generated from data which has been generated from a previous request. Using this pattern, view management is often so trivial (i.e. mapping of an alias to a resource) that no application-level logic is required and it is handled by the container.

Analysis

Avoid

Using User Supplied Forward Values

The ApplicationController determines which view to dispatch to a user. In the Core J2EE Patterns book, the authors provide the following sample of code to determine the next page to dispatch to a user:

next = request.getParameter(“nextview”);

Depending on how you forward users to the next page, an attacker may be able to:

Perform HTTP Response Splitting if the application uses an HTTP redirect to forward the user to the next page. The user supplies the literal value of the destination URL. Because the application server uses that URL in the header of the HTTP redirect response, a malicious user can inject carriage return and line feeds into the response using hex encoded %0A and %0D

Do not rely on literal user-supplied values to determine the next page. Instead, use a logical mapping of numbers to actual pages. For example, in http://siteurl/page?nextview=1 the “1” maps to “edituser.jsp” on the server.

Assuming User’s Navigation History

The Core J2EE Patterns book discusses an example where the Dispatcher View pattern may be used. In the example, the application places an intermediate model in a temporary store and a later request uses that model to generate a response. When writing code for the second view, some developers assume that the user has already navigated to the first view thereby instantiating and populating the intermediate model. An attacker may take advantage of this assumption by directly navigating to the second view before the first. Similarly, if the first view automatically dispatches the second view (through an HTTP or JavaScript redirect), an attacker may drop the second request, resulting in an unexpected state. Always user server-side checks such as session variables to verify that the user has followed the intended navigation path.