TomcatExpert

Cross-Site Request Forgery

posted by mthomas on May 9, 2011 07:08 AM

Cross-site request forgery (CSRF), also sometimes referred to as one-click attacks or session riding, is another type of malicious exploit of websites that the Apache Tomcat community has addressed in the Apache Tomcat 7 release process. Different from cross-site scripting, where the attacker exploits the trust users have for a particular site, CSRF targets the trust that sites have in a user’s browser. The new CSRF Protection prevents attacks directly on Apache Tomcat Manager and Apache Tomcat Host Manager as well as provides a CSRF Prevention Filter for the applications that run on Tomcat to use.

A Simple Example

A system administrator connects to a Tomcat instance and logs into the Tomcat Manager application. The admin performs routine tasks such as deploying a web application, checking the status of another application and upgrading a third application. Then the administrator leaves Tomcat Manager, and goes to browse the web. One of the sites the administrator browses has malicious code in either a link or a flash file that tricks the browser into making a request into Tomcat Manager. The admin’s session for Tomcat Manager has not yet expired, and Tomcat grants the malicious code access to the request. This essentially introduces a large back door for control into the system administrator’s Tomcat instances.

In addition to targeting administrators to take down websites, applications that run on Tomcat-such as banking applications-are also vulnerable to the same attacks. Check out the article on CSRF on the Open Web Application Security Project (OWASP) for more detail.

Is It Really a Vulnerability?

In order for this to work, the attacker must know the full URL for the Tomcat Manager application. Most administrators have a private and unique naming convention for their server infrastructure and ports. The chances of an attacker knowing these is fairly slim, and would essentially mean that it must be a targeted attack on a single deployment.

Another option for attackers is to use localhost with the port 8080 in their request. If the administrator is using Tomcat Manager locally when they are browsing the web, then the attacker would be successful. Usually, however, system administrators would not be running web browsers directly from a production server. For most administrators, this would be considered reckless behavior.

The workaround is simple for any case—when a user is done working on an authenticated session, simply close out the browser or log out of the application so no authenticated session exists to be exploited. For most security sensitive system administrators, this should be a standard operating procedure. However, quite a few security professionals disagree that standard precautions are enough to protect sites, and general consensus is that CSRF is a security vulnerability that applications themselves should protect against.

The Fix

Applications, such as Tomcat Manager, can protect themselves against these types of attacks by using a system of nonces, or tokens. Starting with the authentication request, the browser is sent a special token that must be provided with the next request. Each subsequent response provides a new token for the following request. In this case, when the attacker sends the request, while it will reach the server, it will not include the correct token, so the server will reject the request and prevent the attack.

CSRF Protection in Tomcat 7

Tomcat provides this token-based protection by default in Tomcat Manager and the Tomcat Host Application.

Additionally it provides a CSRF Prevention Filter that can be used by applications deployed on Tomcat 7. The filter sends the token to the browser by modifying all of the URLs in the response for the links that the user can click on. In order to do that, it requires that the application encodes URLs in the response by a calling HttpServletResponse#encodeRedirectURL(String) or HttpServletResponse#encodeURL(String). Web applications should already be doing this as a requirement to support sessions with users that do not accept cookies. However, many web applications today still do not always utilize this method.

For applications that use this format of URL encoding, they can get CSRF protection for free simply by turning on the CSRF Protection Filter.

Addressing Problems with the Back Button & Parallel Requests

Since each request is granted by the validity of the token attached to it, using the back button or parallel requests requires the application to honor previously issued tokens. By default, the CSRF Prevention Filter in Tomcat 7 allows up to the previous 5 tokens to be used. Administrators can change this setting by setting the CSRF Prevention Filter attribute nonceCacheSize to the specific number of previous tokens the application should accept.

Entry points

The URLs protected by the filter will be determined by the configured filter mapping. For example, there is likely to be little point protecting static image files with the CSRF prevention filter. However, there will also be URLs (such as the default page for Tomcat's Manager application) where the filter is required but the nonce check is not required. These URLs are called entry points as they provide a route for user's who do not have a valid CRSF token to entry the protected are of the application. The entry points are configured as part of the filter configuration.

Recommendation

Any application that uses authentication should consider providing CSRF protection. There are a number of libraries available that provide CSRF protection but if you are running on Apache Tomcat 7 then taking advantage of the built-in CSRF prevention filter may provide a simple way to implement this protection.

Note that the CSRF Prevention Filter is now also available in Apache Tomcat 6.

Mark Thomas is a Senior Software Engineer for the SpringSource Division of VMware, Inc. (NYSE: VMW). Mark has been using and developing Tomcat for over six years. He first got involved in the development of Tomcat when he needed better control over the SSL configuration than was available at the time. After fixing that first bug, he started working his way through the remaining Tomcat bugs and is still going. Along the way Mark has become a Tomcat committer and PMC member, volunteered to be the Tomcat 4 & 7 release manager, created the Tomcat security pages, become a member of the ASF and joined the Apache Security Committee. He also helps maintain the ASF's Bugzilla instances. Mark has a MEng in Electronic and Electrical Engineering from the University of Birmingham, United Kingdom.

Comments

Trying to implement this, but having issues

Hi Mark,

I am trying to add CSRF protection to the java web application. I have the web.xml configured with the CSRF filter and filter mappings to the servlets.
[filter]
[filter-name]CSRF[/filter-name]
[filter-class]org.apache.catalina.filters.CsrfPreventionFilter[/filter-class]
[init-param]
[param-name]entryPoints[/param-name]
[param-value]/html,/html/[/param-value]
[/init-param]
[/filter]

[filter-mapping]
[filter-name]CSRF[/filter-name]
[servlet-name]exampleservlet[/servlet-name]
[/filter-mapping]

In my JSP I am try to pass the CSRF_NONCE as a parameter in the POST request
FORM METHOD="POST" ACTION="/exampleservlet"
INPUT TYPE="HIDDEN" NAME="org.apache.catalina.filters.CSRF_NONCE" VALUE="<%=session.getAttribute("org.apache.catalina.filters.CSRF_NONCE")%>"

I keep getting a 403 forbidden. I checked and the NONCE value I am passing is the LRU cache that its suppose to look up and compare with. Not sure why its not finding the NONCE in the cache. Any ideas or help would be appreciated.

Thanks,
Leo

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.