Steve Levine

Archive for the ‘Java’ tag

Simple Security for HTTP Based RESTful Services (Part 1)

without comments

This is going to be the first in a series of posts discussing potential ways of securing bi-directional RESTful based HTTP services. For this series we are going to make the requirements quite simple, namely, “secure” simply means the caller of the service is authorized to invoke it. Lets assume that this solution is being deployed along with a simple IP addresses restriction mechanism. Since IP address’s can easily be spoofed, this solution is the next level of defense to ensure the identity of the caller.

There are many different potential solutions to this problem, but for this series, we are going to focus on the simplest solution which is to add a security hash to each service call. This post assumes you understand how to secure B2B communications with the use of a security hash. If you need a refresher, please refer to this post on the subject.

Since we know the design for securing our communications, we need to decide on an implementation. The first potential implementation we are going to examine is adding a “security hash” to the XML payload for each service call.

The embellished XML payload would look like:

<someEntity>
	<hash>4723af11bef05fc6207bd22cd163d9db</hash>
	<fieldOne> ... </fieldOne>
	<fieldTwo> ... </fieldTwo>
</someEntity>

with the “hash” field (line 2) representing the security hash.

The interface of the SomeEntity service, would look like:

public interface SomeEntityService {
	public void updateSomeEntity(SomeEntity entity, int id) throws SecurityException;
}

with an implementation that looks like:

@Path("/services")
public class SomeEntityServiceImpl {

    @PUT
    @Path("/someEntity/{id}")
    @Consumes("text/xml")
    public void updateSomeEntity(SomeEntity entity,
					@PathParam("id") int id)
						throws SecurityException {
		if (validateHash(entity))
			dao.saveOrupdate(entity)
		else
			throw new SecurityException("Not Authorized");
    }
}

With the actual HTTP Client call looking like:

PUT http://blah.com/services/someEntity/226 HTTP/1.1
Accept: text/xml
Content-Type: text/xml
User-Agent: Jakarta Commons-HttpClient/3.1
Host: somehost:port
Content-Length: 380
<someEntity>
	<hash>4723af11bef05fc6207bd22cd163d9db</hash>
	<fieldOne> fieldOne </fieldOne>
	<fieldTwo> fieldTwo </fieldTwo>
</someEntity>

There you have it, our first potential solution to the problem. We now need to examine if this solution is correct, and if it is, is it elegant?

First things first, is it correct? If you trace through the code, you can see that before the service makes a call to the DAO, it checks to verify the validity of the hash field (line 10). If the hash it is not valid, it will throw an Exception, which in turn would return a 401 to the user. It would not be possible for a client to access the DAO without having the proper hash as part of the XML Payload.

Even though this approach would perform as expected, it has two main issues, the first being it mixes concerns. What we mean by mixes concerns is it mixes business logic with security logic. This is a standard problem that applies to layered architectures. The main side effect of this problem is it makes the code very difficult to reuse. Lets me demonstrate this with a simple code fragment:

// Code in a Web Controller class somewhere
try {
	someEntitySvc.updateSomeEntity(entity);
} catch (SecurityException e) {
	// Nothing we can do... We don't have the hash???
}

As you can see from this simple example the implementation of the service is not generic enough to be usable by a Controller in the Web Tier. Firstly, even if the Web Tier knew about he hash, the code becomes polluted with Exception handling for an Exception that is not applicable to this client. Secondly, the Web Tier simply doesn’t have any knowledge of the hash, and putting logic here to generate the hash just to use the service would not make any sense from a design perspective.

The second issue with this approach is the fact that you can only apply it to Http methods that accept a payload. What about methods that do not accept a Payload, I.e., GET? To make this work for the GET method, we would have to pollute our GET method implementation with a @Consumes(“text/xml”) tag, which functionally would work, but from a API design perspective, it is quite ugly. As a consumer of a GET method, all you need to know is the id of the entity you wish to “get”. Adding an XML payload for “security” purposes is a bad and cumbersome design.

With all that being said, it looks like this is not the best solution to the problem. Stay tuned for part two of this series where we will discuss a more elegant approach to solving this problem.

This entry was posted by Steve on Saturday, November 29th, 2008 at 7:58 pm and is filed under: , , . You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

A little Salt with that Hash?

without comments

Was just presented with a unique (to me) requirement which is to implement a single sign on across multiple domains within the same page via a cookie. Huh? Let me elaborate, in simple terms it means that there is a base site, lets call it foo.com, and then there is a partner site, lets call it bar.com. On foo.com’s main page we want to be able to iFrame in bar.com with the credentials of the current user logged in to foo.com transparently sent over and in turn logged in to bar.com as well.

In order to achieve this, the first thing that needs to happen is the two sites need to have a sub domain in common. The easiest way to accomplish this is to set up an alias on the parent site (foo.com) to bar.com. The alias would be something like bar.foo.com which points to bar.com. This is required because if they do not have a domain in common there is no way for them to share cookies.

The next thing that needs to happen is both sites have to agree on a way of authenticating a user. In our case we used a cookie that consisted of the user id followed by a hash of the user id which looked something like 12345,jfk83jf835jfiie43.

Your probably wondering how this simple cookie can facility a single sign on across two different sites? Let me explain, first lets talk about the how the values of the cookie are generated. The first value, namely, the user id, is self explanatory. The second part of the cookie, the hash, has a little bit more to it. In order to effectively use the hash, the two sites need to have a “shared secret” aka “The Salt” that only they know.

In order to generate the hash, you append the salt to the user id, and then run it through a one way hashing function. The result is a unique key that can only be generated by the two parties who know the salt (or generated by anyone who knows the salt, so make sure the salt stays very secure). Since it is a one way function, it would be very difficult for someone to reverse engineer it.

Now that we have the id and the hash explained, lets talk about how bar.com can use this to authenticate the user. When a user on Foo.com first logs in, the shared cookie is created by foo.com, and when they hit a page in the iFrame which is pointing to bar.com, bar.com checks the cookie. If it is there, it has the user id and hash of the remote user.

Step one for bar.com is to take the user id, hash it (based on the agreed upon salt), and first verify that it matches the hash that is supplied as the second part of the cookie. If it matches, it is safe for bar.com to assume the user id in the cookie is the user id of the remote user, thus bar.com can log the user in.

This method is not the most secure method of doing a single sign on as a hacker can easily do a man in the middle attack and thus obtain the cookie, and hash, and then with the user id and hash in hand, can easily log in to bar.com as the remote user.

There are a few precautions you can take if you choose to use this method like adding values to the salt like, date, time, request id, that would make the request unique not only to a user, but to a specific time of day or a specific request. Another approach you can take to make this more secure is to simply use SSL across the wire.

Keep in mind we used this method as a simple way of verifying user identity, we were not concerned with either site getting hacked as we had other security mechanisms in place.

So, please take this approach with a grain of salt.

This entry was posted by Steve on Thursday, October 30th, 2008 at 7:06 pm and is filed under: , . You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Proposed Java 7 Feature: Safe Rethrow

with one comment

How many times have you written the following code:

void someMethod() throws X1,X2 {
  try { /* Something that can throw X1,X2 */ }
  catch (Throwable e) {
    logger.log(e);
    throw e; // Error: Unreported exception Throwable
 }
}

Need a way to express we are simply re-throwing the Exception that was caught.

The Proposal to add the safe re-throw to the language is as follows:

void m() throws X1,X2 {
   try { /* Something that can throw X1,X2 */ }
   catch (final Throwable e) {
      logger.log(e);
      throw e; // Compiles OK; can throw X1,X2
   }
}

Again, lets hope it makes its way in to Java 7.

This entry was posted by Steve on Wednesday, June 25th, 2008 at 11:58 am and is filed under: , . You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Proposed Java 7 Feature: Multi-Catch Statements

without comments

How many times have you written code where you have something along the lines of:

 try { do something interesting ... }
     catch (X1 e1) { close(); }
     catch (X2 e2) { close(); }
     catch (X3 e3) { cleanup(); }
 

It is cumbersome to have to catch X1 and X2 separately even though they perform the same action if an Exception is raised. Wouldn’t it be nice if there was a way to catch both X1 and X2 with one single catch block?

Enter the Java 7 proposal for Multi-Catch statements. If/when this proposal makes it in to the language, it would eliminate the need to have a catch statement for each Exception. It facilities a mechanism to catch multiple Exceptions, and then perform the same action on them eliminating the need to have one catch per Exception thrown.

 try { do something interesting ... }
    catch (X1, X2 e1) { close(); }
    catch (X3 e ) { cleanup(); }

Now isn’t this code much cleaner? Let’s hope it makes it in to the next version of Java.


This entry was posted by Steve on Tuesday, June 10th, 2008 at 10:21 am and is filed under: , . You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Fork me on GitHub Fork me on GitHub