TurboManage

David Chandler’s Journal of Java Web Development

  • David M. Chandler

    15-yr veteran of Web apps residing in Atlanta with the wife of my youth and our five children. My current project is ROA, a prayer list keeper written in GWT for AppEngine. In my "spare" time, I take pictures, preferably of Rocky Mountain National Park like the one above in which I am waving from The Keyhole.

  • My Google Notebooks

  • Blog Stats

    • 38,412 hits

Archive for the ‘Web App Security’ Category

Calling AppEngine (securely) from GWT with gwt-dispatch

Posted by David Chandler on October 7, 2009

When using an AJAX framework like GWT, it is necessary to authenticate each service call as well as the front end or else your services are open to the world. With AppEngine, there are several approaches we could take, such as wrapping all service servlets with a servlet filter or Spring Security or calling a checkLoggedIn() method as the first statement in each service method.

The mechanics of authenticating an AppEngine on the server side are simple enough. We just call the AppEngine UserService. The browser automatically passes the AppEngine cookie with each service request, so we don’t have to modify our service interfaces just to authenticate the user. This example shows a simple checkLoggedIn() method that could be called from each service method or wired into a servlet filter:

package com.turbomanage.server.util;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.turbomanage.exception.NotLoggedInException;

public class ServiceUtil
{
	public static User checkLoggedIn() throws NotLoggedInException
	{
		User user = getUser();
		if (user == null)
		{
			throw new NotLoggedInException("Not logged in.");
		}
		return user;
	}

	private static User getUser()
	{
		UserService userService = UserServiceFactory.getUserService();
		return userService.getCurrentUser();
	}
}

In addition to authenticating the user, it’s a good idea to protect our services against CSRF/XSRF attacks. Google recommends (see section on XSRF and GWT) that each service request be accompanied by a token that is available to the server and the client application, but not to JavaScript code in an email link or running on other  pages. The simplest scheme is simply to pass the sessionId cookie as an argument to each service method. With standard GWT-RPC, however, this is a pain because we have to add an argument to every method of every service:

public interface MyService extends RemoteService {
  public boolean doSomething(String cookieValue);
  public void doAnotherThing(String cookieValue, String arg);
}

This is where gwt-dispatch comes to the rescue and makes you thankful for people who turn verbs into nouns. Because gwt-dispatch uses the Command pattern, all standard GWT-RPC services are replaced with a single DispatchService that accepts an Action and Result argument. Each method in a standard GWT-RPC service is now represented by a corresponding Action and Result class. Because there is now only one real GWT-RPC service, the DispatchService, and because its execute method gets called for every request, we now have only place we need to add a session token argument. The gwt-dispatcher SecureDispatchService does exactly this:

package net.customware.gwt.dispatch.client.secure;

import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.Result;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("dispatch")
public interface SecureDispatchService extends RemoteService {
    Result execute( String sessionId, Action<?> action ) throws Exception;
}

By implementing this service on the server, we now have one place where we can verify the user is logged in as well as verify that the session ID passed as an argument with the request matches the session ID cookie sent automatically by the browser.

So here is my take on an AppEngineDispatchService that builds on gwt-presenter’s SecureDispatchService to achieve both user authentication and a measure of CSRF/XSRF protection. Because gwt-presenter’s SecureDispatchAsync class has a dependency on its own SessionUtil class, I had to replace it with AppEngineDispatchAsync; however, this could easily be factored out as an interface in a future release of gwt-presenter (and indeed has been already on the server side).

One last thing to mention: AppEngine uses a cookie named “ACSID”, so that’s what we’re passing with each request.

Our first class is just a stripped-down version of gwt-presenter’s SecureDispatchServiceAsync which passes the AppEngine session ID as an argument with each request.

package com.turbomanage.gwt.client.dispatch;

import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.Result;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.turbomanage.gwt.client.service.AppEngineDispatchService;
import com.turbomanage.gwt.client.service.AppEngineDispatchServiceAsync;

/**
 * An AppEngine-aware implementation of {@link DispatchAsync}
 *
 * (c) 2009 David M. Chandler
 * Licensed under the Apache License, Version 2.0
 */
public class AppEngineDispatchAsync implements DispatchAsync {

    private static final AppEngineDispatchServiceAsync realService = GWT.create( AppEngineDispatchService.class );

    public AppEngineDispatchAsync() {
    }

    /* (non-Javadoc)
	 * @see com.turbomanage.gwt.client.dispatch.AppEngineSecureDispatchServiceAsync#execute(A, com.google.gwt.user.client.rpc.AsyncCallback)
	 */
    public <A extends Action<R>, R extends Result> void execute( final A action, final AsyncCallback<R> callback ) {

    	// Get AppEngine session ID
        String sessionId = Cookies.getCookie("ACSID");

        realService.execute( sessionId, action, new AsyncCallback<Result>() {
            public void onFailure( Throwable caught ) {
                callback.onFailure( caught );
            }

            public void onSuccess( Result result ) {
                callback.onSuccess( ( R ) result );
            }
        } );
    }

}

To use this class instead of gwt-presenter’s Standard or SecureDispatchAsync, simply modify the binding in your GIN module:

    @Override
    protected void configure() {
    ...
        bind( DispatchAsync.class ).to( AppEngineDispatchAsync.class ).in( Singleton.class );
    ...
    }

Now for the service interfaces. These are just renamed from gwt-presenter’s SecureDispatchService and SecureDispatchServiceAsync, which was necessary because I could not use gwt-presenter’s SecureDispatchServiceAsync on account of the above-mentioned dependency on SessionUtil and GWT seems to require that a service and its corresponding Async class exist in the same package.

package com.turbomanage.gwt.client.service;

import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.Result;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("dispatch")
public interface AppEngineDispatchService extends RemoteService {
    Result execute( String sessionId, Action<?> action ) throws Exception;
}

And the corresponding Async interface, likewise just renamed from gwt-presenter’s SecureDispatchServiceAsync:

package com.turbomanage.gwt.client.service;

import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.Result;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface AppEngineDispatchServiceAsync
{
	void execute(String sessionId, Action<?> action,
			AsyncCallback<Result> callback);
}

Finally, our server implementation of the DispatchService:

package com.turbomanage.gwt.server.service;

import java.util.logging.Logger;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import net.customware.gwt.dispatch.client.secure.SecureDispatchService;
import net.customware.gwt.dispatch.server.Dispatch;
import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.Result;
import net.customware.gwt.dispatch.shared.secure.InvalidSessionException;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.turbomanage.gwt.client.service.AppEngineDispatchService;

/**
 * A servlet implementation of the {@link SecureDispatchService}. This verifies
 * that an AppEngine user is logged in and inspects the passed AppEngine
 * session ID to prevent CSRF/XSRF attacks
 *
 * (c) 2009 David M. Chandler
 * Licensed under the Apache License, Version 2.0
 */
@Singleton
public class AppEngineDispatchServiceServlet extends RemoteServiceServlet
		implements AppEngineDispatchService
{
	private static final long serialVersionUID = -1456388230348266500L;
	private static final Logger LOG = Logger.getLogger(AppEngineDispatchServiceServlet.class
			.getName());

	private final Dispatch dispatch;
	private Provider<HttpServletRequest> req;

	@Inject
	public AppEngineDispatchServiceServlet(Dispatch dispatch, Provider<HttpServletRequest> req, Provider<ServletContext> context)
	{
		this.dispatch = dispatch;
		this.req = req;
	}

	public Result execute(String clientSessionId, Action<?> action) throws Exception
	{
		try
		{
			String serverName = req.get().getServerName();
			UserService userService = UserServiceFactory.getUserService();
			User user = userService.getCurrentUser();
			if (user != null)
			{
				// User is logged in, now try to match session tokens
				// to prevent CSRF
				String sessionId = "";
				Cookie[] cookies = req.get().getCookies();
				for (Cookie cookie : cookies)
				{
					if (cookie.getName().equals("ACSID"))
					{
						sessionId = cookie.getValue();
						break;
					}
				}
				// Skip check on localhost so we can test in AppEngine local dev env
				if (("localhost".equals(serverName)) || (sessionId.equals(clientSessionId)))
				{
					return dispatch.execute(action);
				}
			}
			throw new InvalidSessionException();
		}
		catch (RuntimeException e)
		{
			LOG.warning("Exception while executing " + action.getClass().getName()
					+ ": " + e.getMessage());
			throw e;
		}
	}
}

For each request, we’re simply calling the AppEngine UserService to verify the user is logged in and attempting to match the AppEngine cookie passed as an argument with the one passed as a cookie. In order to get access to the cookie on the server, we utilize a Guide Provider that lets us get to the ServletRequest. Likewise, we obtain the ServletContext in order to get the server name and skip the CSRF check on localhost, since AppEngine doesn’t set the ACSID cookie when running in the local development environment.

Lastly, we replace the gwt-presenter Standard or SecureDispatchServiceServlet with our AppEngine equivalent in the server’s Guice module:

	@Override
	public void configureServlets()
	{
		// NOTE: change the servlet context for your app
		serve("/your_app/dispatch").with(AppEngineDispatchServiceServlet.class);
	}

Thanks to gwt-presenter and the Command pattern, every AppEngine service request in our application now checks for a logged in user and provides a measure of CSRF protection.

Posted in AppEngine, Google Web Toolkit, Model-View-Presenter, Web App Security | 6 Comments »

Securing JSF Applications Against the OWASP Top Ten

Posted by David Chandler on October 6, 2009

My JSF security presentation in now available in PDF format from the Writings page above.

Posted in JavaServer Faces, Web App Security | Leave a Comment »

MyFaces Security Presentation Now Available

Posted by David Chandler on October 11, 2006

My ApacheCon presentation, Securing MyFaces Applications Against the OWASP Top Ten, has been updated for OWASP 2007 and is available here as well as directly from my Writings page above (along with video).

Securing JSF Applications Against the OWASP Top Ten (PowerPoint)

/dmc

Posted in JavaServer Faces, Web App Security | 1 Comment »

Securing MyFaces Applications Against the OWASP Top Ten

Posted by David Chandler on August 17, 2006

Update Oct 6, 2009: you can download this presentation from the Writings page above.

My presentation on this subject has been selected for the upcoming ApacheCon US 2006! If you’d like to be a technical reviewer beforehand, please e-mail me at the address on the Consulting menu above. See you there!

ApacheCon US 2006

The JavaServer Faces (JSF) API is an excellent foundation for building secure Web applications because of its component-oriented nature, carefulness surrounding data validation, and numerous extension points. Apache myFaces builds on this strength by providing components which offer built-in protection against many of the OWASP Top Ten attacks including form parameter tampering and cross-site scripting. In this presentation, we’ll review how myFaces protects against these attacks and move on to explore JSF extensions you can deploy to provide complete protection against the OWASP Top Ten, including forced browsing, information leakage in select boxes, and unauthorized method execution. Specifically, we’ll look at centralized approaches to ensuring that every field and form is properly validated, a phase listener and view handler to prevent forced browsing and assist with detection of session hijacking, a customer converter and component to hide sensitive information such as IDs in menu options, and a JAAS permission checker for component actions (event handler methods).

/dmc

Posted in JavaServer Faces, Web App Security | Leave a Comment »

Disable Browser Caching in JSF

Posted by David Chandler on August 8, 2006

Browser caching of page content has negative security implications when your application runs on shared terminals (like the public library). You can turn it off with this simple phase listener. Well, maybe. As some of the comments indicate, browsers are finicky, and of course, we never trust the browser, anyway, so using this technique is certainly not a security guarantee of any kind.

package my.util;

import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletResponse;

public class CacheControlPhaseListener implements PhaseListener
{
	public PhaseId getPhaseId()
	{
		return PhaseId.RENDER_RESPONSE;
	}

	public void afterPhase(PhaseEvent event)
	{
	}

	public void beforePhase(PhaseEvent event)
	{
		FacesContext facesContext = event.getFacesContext();
		HttpServletResponse response = (HttpServletResponse) facesContext
				.getExternalContext().getResponse();
		response.addHeader("Pragma", "no-cache");
		response.addHeader("Cache-Control", "no-cache");
		// Stronger according to blog comment below that references HTTP spec
		response.addHeader("Cache-Control", "no-store");
		response.addHeader("Cache-Control", "must-revalidate");
		// some date in the past
		response.addHeader("Expires", "Mon, 8 Aug 2006 10:00:00 GMT");
	}
}

To register the phase listener, just add this to your faces-config.xml:

	<lifecycle>
		<phase-listener id="nocache">my.util.CacheControlPhaseListener</phase-listener>
	</lifecycle>

Posted in JavaServer Faces, Web App Security | 25 Comments »

JSF Security Presentation at OWASP Atlanta Wed Aug 9

Posted by David Chandler on August 8, 2006

Securing JavaServer Faces Applications Against the OWASP Top Ten Attacks

This is a preview of the talk I’ll be giving at ApacheCon US in October.

When: Wednesday August 9th 6:30pm – 8:00pm

Location:
Thoughtmill – MapQuest <http://www.mapquest.com/directions/main.adp?go=1&do=nw&rmm=1&un=m&cl=EN&ct=NA&rsres=1&1ahXX=&1y=US&1a=&1c=&1s=&1z=&2ahXX=&2y=US&2a=2520+Northwinds+Parkway%2C+Suite+300&2c=Alpharetta&2s=Ga&2z=30004>
Two Northwinds Center
2520 Northwinds Parkway, Suite 300
Alpharetta, GA 30004
tel: 678.566.4700
fax: 678.566.4861

This meeting is open to public and admission is free.

OWASP Atlanta – our mission as a local chapter of the Open Web Application Security Project is to help promote awareness and contributions to web application security.

Who Should Attend – anyone interested in Web Application Security (management, security architects, developers, etc)

Please RSVP for this event. Send email to cburkeinga “at” hotmail and also Register to OWASP Atlanta mailing list at: http://lists.sourceforge.net/lists/listinfo/owasp-atlanta/

Keynote Speaker: David Chandler
Abstract:
The JavaServer Faces (JSF) API is an excellent foundation for building
secure Web applications because of its component-oriented nature,
carefulness surrounding data validation, and numerous extension points.
Apache myFaces builds on this strength by providing components which
offer built-in protection against many of the OWASP Top Ten attacks
including form parameter tampering and cross-site scripting. In this
presentation, we’ll review how myFaces protects against these attacks
and move on to explore JSF extensions you can deploy to provide complete
protection against the OWASP Top Ten, including forced browsing,
information leakage in select boxes, and unauthorized method execution.
Specifically, we’ll look at centralized approaches to ensuring that
every field and form is properly validated, a phase listener and view
handler to prevent forced browsing and assist with detection of session
hijacking, a customer converter and component to hide sensitive
information such as IDs in menu options, and a JAAS permission checker
for component actions (event handler methods).

Speaker Biography:
David Chandler is a Java Web Architect in Atlanta, GA, where he has been developing a next-generation platform for Internet banking applications. An electrical engineer by trade, Chandler got hooked on developing dynamic Web applications in 1994 and hasn’t looked back since. Having written Web applications in C, perl, ColdFusion, and Java, Chandler is a huge fan of tools like Hibernate and JSF that bring together the robustness and expressiveness of Java along with the speedy development that once belonged only to scripting languages. Chandler holds a patent on a method of organizing hierarchical data in a relational database and is the author of the best-selling Running a Perfect Web Site (Que, 1995).

Posted in JavaServer Faces, Web App Security | 2 Comments »