Top Linux Links You Must Click On


How to Create Secure Web Applications with Struts
Imagine building a house starting with only a pile of timber and a lump of iron

So how can we use the Validator plug-in to improve security?

1.  Think "White List" - Most common attacks based on input validation flaws leverage special "meta-characters" to inject user-modifiable data into places it shouldn't be. A typical security mistake developers make is to try to recognize, clean, or escape known "bad" values rather than accept only "good" values. This becomes a problem when a new "bad" value is discovered. With the enormous number of different locales, encodings, syntaxes, and variations thereof, it's likely this strategy will fail, or at least be difficult to maintain. Struts Validator plug-in lets users verify that input data conforms to strict requirements and is well formed. The validation routines Struts uses can leverage regular expressions (with the mask field) to ensure that only safe strings are accepted. Sometimes, it may be necessary to accept some malicious characters, but it's important to handle them very carefully. Furthermore, data can be verified to ensure that it's within reasonable length bounds to avoid denial-of-service-style attacks.

2.  Be Consistent - Using the Validator plug-in, it's significantly easier to verify that there are no holes in the input validation mechanism. This means that all the data from the user should be in a ValidatorForm class and all fields should be specified in the validation framework. This can be checked simply by matching XML elements and it's much easier to discern than having widespread, inconsistent input validation schemes.

3.  Be Strict - Furthermore, there are some cases where it's preferable to let the user select a few values from a finite list than to let him enter arbitrary data (for example, in cases of a yes/no, multiple choice, or filename). When designing input forms, it's good practice to constrain the possible values as narrowly as possible and reinforce these constraints through validation.

Struts and Access Control
One of the main principles of security is access control (also called authorization) - making decisions on who can and can't do what. Operating systems, file systems, databases, and other systems that must enforce security requirements all contain some sort of access control system to prevent malicious and/or inappropriate usage or resources. In Java Web applications using JAAS (Java Authentication and Authorization Service) and similar mechanisms, there are two different approaches for enforcing access control: declarative and programmatic. Declarative access control means specifying users, roles, and security constraints in configuration files, while programmatic access control declares and implements this logic in the code. The decision to use either approach depends on requirements, but generally declarative access control is easier to implement but inflexible, while programmatic access control requires custom coding but is largely customizable.

The Struts framework, as a whole, is built to be extensible, and this is one of its major strengths. Whether an application uses declarative or programmatic access control, Struts has built-in support and extension points for fulfilling access control requirements.

Declarative Access Control
The Struts framework has a role-based access control mechanism for securing actions declaratively. In struts-config.xml, each action has a roles attribute, which accepts a comma-separated list of available roles:

<action path="/AdminLogin"
      forward="/admin_login.jsp"
      roles="administrator"/>

This allows for a more natural approach to access control based on the named Action classes rather than URL patterns. One important thing to note is that this doesn't secure JSPs, HTML, or other non-Action resources. If all JSPs are only accessible through the controller (which is a Struts/MVC best practice), a recommended countermeasure is to put all JSPs in the WEB-INF folder so they aren't directly available to users. However, this requires that the container stipulates that files in the WEB-INF folder aren't accessible to Web users. Otherwise, JSPs can be protected by standard security constraints in the configuration file.

Programmatic Access Control
The Struts framework offers several different extension points where programmatic access control can be implemented. Specifically, the request processor has a processRoles() method that can be extended to do custom programmatic access control for all requests to the application:

protected boolean processRoles( HttpServletRequest request,
     HttpServletResponse response,
     ActionMapping mapping )
   throws IOException, ServletException {
     ...
     if (request.isUserInRole(roleName)) {
     ...
}

There are other places that access control could occur, including Servlet Filters and ActionServlets, which will be discussed in the struts and Cross-Cutting Security Concerns section.

Additionally, Struts has tag libraries to support programmatic "content-level" access control in JSP pages. Using the following tag, content in JSP pages can be secured according to roles:

<logic:present role="administrator"/>
<a href="admin_page.jsp">Administrator Home</a>
</logic:present>

In almost all cases, it's recommended that you use the security mechanisms built into the containers and frameworks rather than write them from scratch. Struts provides a granular, integrated set of role-based access control functionalities that help teams design and implement secure applications.

Struts and Error Handling
Application hackers are very resourceful; any piece of information uncovered during an attack will be noted, analyzed, and leveraged for future attacks. One of the most useful (read compromising) pieces of data that a hacker can access is an error messages that says too much about the internal workings of the application. This lets the attacker make informed decisions about the effectiveness of the attack, how to proceed in further attacks, and what resources are accessible by the application.

Struts has a very powerful and extensible exception-handling mechanism built-in. It's very important, for security's sake, to use this carefully to improve the user experience without letting information leak to malicious attackers. Specifically, it's important to have robust error handling, so that expected errors (e.g., bad logins) are handled as appropriately as unexpected errors (NullPointerExceptions) and that there are good logging facilities to verify security-relevant events.

For Java Web applications in general, there are several ways to catch exceptions.

  • Programmatically:
    1.  Use try/catch blocks.

    try {
        login(username, password);
    } catch (BadLoginException) {
    ...
    }

    2.  Use the JSP page directive "errorPage".

    <%@ page errorPage="bad_login.jsp" %>

  • Declaratively:
    3.  In Web.xml, declare error-page and exception type forwards.

    <error-page>
        <exception-type>
          com.jdjexample.BadLoginException
        </exception-type>
        <location>/bad_login.jsp</location>
    </error-page>

  • About Alex Smolen
    Alex Smolen is a Software Security Consultant at Foundstone, where he provides security consulting services to clients to help find, fix, and prevent security vulnerabilities in enterprise software. His duties include threat modeling, code review, penetration testing and secure software development lifecycle (S-SDLC) design and implementation. Alex’s speaking engagements include Enterprise Architect Summit 2005 where he spoke on emerging trends in enterprise security as well as Better Software Conference 2005. Alex graduated from the University of California, Berkeley, with a BS in electrical engineering and computer science.

    In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    Imagine building a house starting with only a pile of timber and a lump of iron, or making a bowl of spaghetti from a sack of wheat and a bag of tomatoes. The importance of having the right materials makes the idea of building products from scratch seem absurd. Similarly, any software project that doesn't take advantage of the numerous frameworks available for any manner of development activity could be wasting valuable resources and ignoring established best practices.

    Imagine building a house starting with only a pile of timber and a lump of iron, or making a bowl of spaghetti from a sack of wheat and a bag of tomatoes. The importance of having the right materials makes the idea of building products from scratch seem absurd. Similarly, any software project that doesn't take advantage of the numerous frameworks available for any manner of development activity could be wasting valuable resources and ignoring established best practices.


      Subscribe to our RSS feeds now and receive the next article instantly!
    In It? Reprint It! Contact advertising(at)sys-con.com to order your reprints!
    ADS BY GOOGLE
    Subscribe to the World's Most Powerful Newsletters