TurboManage

David Chandler's Journal of Java Web and Mobile Development

  • David M. Chandler


    Web app developer since 1994 and Google Cloud Platform Instructor now residing in Colorado. Besides tech, I enjoy landscape photography and share my work at ColoradoPhoto.gallery.

  • Subscribe

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 224 other subscribers
  • Sleepless Nights…

    March 2023
    S M T W T F S
     1234
    567891011
    12131415161718
    19202122232425
    262728293031  
  • Blog Stats

    • 1,039,383 hits

Archive for the ‘Web App Security’ Category

Are Private Clouds Really Safer?

Posted by David Chandler on June 24, 2011

For the second time in two weeks (first in Detroit, then in Atlanta), I’ve listened to a panel discussion on cloud computing in which a panelist has claimed that private clouds are safer than “The Cloud.” In both cases, the panelist was a data center vendor (hmmm…) and in both cases, the other panelists were not so readily agreed. The vendor rep in Atlanta kept mentioning the possibility of network sniffing, as though someone might be able to penetrate Amazon’s hardware virtualization, gain access to the real Ethernet controller, put it in promiscuous mode, and then sniff traffic on … the one wire running to the switch?

Bob Reid of the kotter group asked the best question of the evening: is there any empirical evidence that public cloud computing is safer than private cloud? In other words, has anyone ever successfully penetrated Amazon’s hardware virtualization, App Engine’s VM, etc. and used it to obtain other customers’ data? Said data center vendor acknowledged that social engineering is a much more likely attack vector and can be used just as successfully in a private cloud as public, but then repeated his concerns about the public cloud without citing any evidence. Thankfully, Dennis Hurst, founder of the Cloud Security Alliance, nailed it: the studies show that most break-ins are due to application design flaws and have nothing to do with the hosting environment.

There’s no doubt that some CxOs get a warm fuzzy from knowing that their data is on “their own” servers; however, this would appear to be a false sense of security. If anything, public cloud providers are safer (Dennis Hurst alluded to this earlier in the discussion) because security is an inherent design consideration. All public cloud providers rely on some form of virtualization, whether at the hardware layer (AWS) or a Java VM with security restrictions like App Engine and no doubt do continuous testing to ensure the security of the virtualization layer. The strength of the security sandbox is fundamental to the offering, and public cloud providers can afford to employ the best and brightest to get it right (unlike regional data center vendors–are you sure you’ve got the latest patches?).

Furthermore, public cloud offerings are typically built around services like AWS’s SimpleDB and App Engine’s Datastore, which are not subject to attacks like SQL injection because the service APIs don’t allow you to execute arbitrary database commands. Service APIs significantly limit attack surface, which is one reason why I prefer App Engine’s approach to virtualization over Amazon’s (granted, I’m a little biased). With AWS, you’re still responsible to configure your virtual machine instances correctly, albeit you have to explicitly open network ports so you’re not wide open by default.

The question, I think stands: is anyone aware of an incident in which a public cloud customer obtained access to another customer’s data by penetrating the security sandbox? Methinks the cloud offerings of today are generally much safer than the shared Web hosting arrangements of the past because of the superior virtualization technology employed today. Once upon a time, you could use CFFILE on a mis-configured ColdFusion host or similar technique in ASP to gain access to the file system on the shared host. But as far as I know, no one has demonstrated such an exploit against AWS, App Engine, Azure, etc.

Social engineering, insider leaks, and application flaws (which are arguably *less* likely using public cloud services) remain the most likely attack vectors, and CxOs should carefully evaluate FUD from data center vendors before rejecting the public cloud on the basis of security concerns. And while I’m at it, unless a “private cloud” offers elasticity, multi-tenancy, and metered service, I don’t think it can properly be called cloud. Dedicated / colocated hosting has been around for a long time and has its merits, but please don’t “cloud” the vocabulary.

Advertisement

Posted in AppEngine, Web App Security | 1 Comment »

Be careful with yesterday’s post

Posted by David Chandler on February 23, 2010

Just in case you missed the comments on yesterday’s “Generic” Objectified ActionHandler, the example code potentially exposes your Datastore to hackers who can spoof or otherwise modify GWT-RPC requests. Be sure to read the comments, and if you’ve never seen Paros, TamperData (Firefox plug-in) or the like, you might want to check those out to see just how easy it is to modify Web requests in ways the developer did not intend. It’s not as easy to modify GWT-RPC because it’s a binary (serialized) protocol, but it’s not encrypted so it certainly is possible.

Bottom line: your server-side code should always check user permissions one way or another. SecureDispatchService (gwt-dispatch) will restrict access to ActionHandlers to only authenticated users, but depending on how many hackers you have in your user base and how private the data needs to be, you may need additional permission checking on each persistence-related action.

You have been warned.

Posted in AppEngine, Google Web Toolkit, Web App Security | Leave a Comment »

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, GIN / Guice, Google Web Toolkit, Model-View-Presenter, Web App Security | 23 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 | 5 Comments »

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 | 65 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 | 3 Comments »

 
%d bloggers like this: