Monday, November 10, 2008

CSRF Prevention in Struts 2


Cross-site request forgery, one of the OWASP Top 10 vulnerabilities for 2007, is an attack in which a malicious user causes a victim's browser to make a request without the user's consent. This attack is generally propagated by a third party site.

The example below shows how a CSRF attack might affect a web application that allows customers to request rental movies to be mailed to their house.

A customer logs into her movie rental web site and selects some movies to add to her queue. Next, instead of logging out of the application, she types in the address for her favorite news site, reads a few online comics, and does some research on used cars.

Unfortunately, before the customer began her research, an attacker had discovered a persistent cross-site scripting vulnerability on one of the used car sites. The attacker had also exploited this vulnerability to include a simple image tag containing a URL similar to the one below:

<img src="" />

When this image tag loaded in the customer's browser, a request was sent to the movie rental application to add an embarrassing movie to the beginning of the customer's queue.

One strategy to address CSRF attacks is to require and validate one-time values included in requests to sensitive functionality. For more information, please view the OWASP explanation found here.

Struts 2 tokenSessionInterceptor

The tokenSessionInterceptor, provided by struts 2, allows developers to add CSRF protection quite easily. In the example below, the tokenSessionInterceptor was added to the interceptor stack. A parameter has been passed to the interceptor to ensure it will not be triggered on each request.

In the ProcessSimpleLogin action, the tokenSessionInterceptor is referenced again. In this case, a parameter is passed to the interceptor to ensure it verifies a valid token has been sent for this action only.

(Click the image above to view the XML)

In order to include the proper token within the page, the <s:token /> tag is included as shown below.

(Click the image above to view the code)

This strategy ensures the ProcessSimpleLogin action executes only if a one-time token has been associated with the user's session, the request includes this token, and the token has been used only one time.

The code repository containing updated struts 2 modules can be found below:

Additionally, you can see discussion of these modules in my earlier blog posts:


Anonymous said...

Thanks for the useful post! Would be great if the XML could be copyable text instead of an image.

Nick Coblentz said...

Yeah, its inconvenient for sure. So, I put all the code here to download: