|
|
|||||||||||||||||||||||||||||||||||||||||||||
Elie Levy's Blog
JavaOne - Extending Swing: Creating your own componentsPosted by elevy on May 30, 2008 at 10:31 AM | Permalink | Comments (5)The JavaOne slides are available now for download. My session on how to extend the swing API creating your own components can be reached at: Extending Swing: Creating your own components Thank you all for the positive feedback you have gave me, it was a great experience! Securing the integrity and authenticity of linksPosted by elevy on May 13, 2008 at 12:40 PM | Permalink | Comments (1)It has been a while since my last posting. As you can imagine, I have been really busy. Last week I was presenting at the JavaOne, and it was amazing. Thank you all for all the positive feedback on my session. I will most likely writing something about the demos I showed, and may be I will post them here with Java WebStart. That will have to wait for now... Now back to the blog that I have been thinking to write: Form hidden fields, query string arguments, and cookie values are frequently used as parameters to keep session state on the client of web based application. In this blog, I explore an option for securing those values. The key to this approach is that even if the developer is unaware of the problem, they are safe, thanks to the underlining framework. The problem is that it is extremely easy for an attacker to change the values of any of these parameters. Making the Web Application vulnerable if the developers are not careful. My first recommendation to address this problem is to avoid using those parameters in the first place. If that is not possible, then strong validation is necessary. However, there are some cases where that validation is not easy to do. How do you achieve security? In this blog, I am going to describe a solution for the parameters in the query string. It would be trivial to extrapolate it and apply it to the other cases. The idea is to use a keyed-Hash Message Authentication Code (HMAC). HMAC is just a hash value combined with a private key. In this case we are going to use it as a checksum. The idea is to get the URL with the parameters, pass it through the HMAC algorithm, and append this "checksum" to the query string. In this way when we receive a URL we can calculate the checksum again. If it matches, we know that the URL was generated from our application. If it doesn't, ALARM! someone modified the query string. A problem that we would still have, is that if someone was to be able to get to the computer of an authorized user, after looking at the browse history, the attacker can replicate the requests, and potentially violate the system security. A way to stop that from happening would be to include a timeout as part of the query string, and then obtain the HMAC. The validation phase would include validating that the timeout has not expired. There is no constraint that does not have side effects. In this case, a bookmark would only be good for the lifetime of the session (until the timeout of the query string is good). I personally don't think of this as a problem, on the contrary I see this as a benefit. The links that we would protect using this technique, are the type of links we would not want the user to bookmark in the first place. Now that we have gone through the theory, let's see some code of what would it take to implement something like this. In this case, I will extend the struts framework. Obviously, the same idea can be applied to almost any other framework as well. The first step will be to identify which Actions are going to have this security. For that we can extend the Action Mapping class to include a requireHMAC parameter:
public class SecureActionMapping extends RequestActionMapping {
protected boolean requiresHMAC;
public boolean getRequiresHMAC() {
return requiresHMAC;
}
public void setRequiresHMAC(boolean requiresHMAC) {
this.requiresHMAC = requiresHMAC;
}
}
Then in the struts-config.xml file we need to configure struts to use this as the ActionMapping class:
<action-mappings type="org.zilonis.hmaclinks.SecureActionMapping">
.... all the action mappings
<action path="/editUser" type="EditUserAction">
<set-property property="requiresHMAC" value="true"/>
</action>
</action-mappings>
In the Struts html tag library we have the custom tag html:link. To generate the links all we need to do is extend it to include the HMAC and the timeout as part of the link. To generate the HMAC:
private final static JTIME="&time=";
private final static HMAC="&jval=";
public static String appendHMACSecurity(String url) {
url+= JTIME + System.currentTimeMillis();
url+= HMAC + HMACGenerator.genHMac(url);
return url;
}
public class HMACGenerator {
private final static SecretKey key = genKey();
public static String getMac(String url) {
Mac mac = Mac.getInstance(key.getAlgorithm());
mac.init(key);
byte utf8[] = url.getBytes("UTF8");
byte digest[] = mac.doFinal(utf8);
String result = URLEncoder.encode(new Base64Encoder.encode(digest));
}
private final static SecretKey genKey() {
KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
return keyGen.generateKey();
}
}
I have omited purposely Exception handling for readability. An interesting trick here is that I am generating the key in a static final field. That means that the first time the application gets started, the private key is going to be generated. In this way, there is no need to have any key management procedures with the operations team. If you were on a situation that your application does not get restarted in a long time (more than 15 days) you might want to considering putting some code there to generate a new key every now and then... To verify the HMAC we just need to extend the FrontProcessor servlet to check if the action requires an HMAC. Then a similar piece of code to generate the HMAC and compare it with the one we are receiving. Notice that we are not decrypting the HMAC. The HMAC never gets decrypted. All we do is generate again our "checksum" and verify that it is the same we are receiving. Finally we just need to check the timeout. This technique might be overkill for some environments. But there are some situations where other options are not really feasible. This is easy enough to turn on/off on any use case you application might have. |
June 2008
Search this blog:CategoriesCommunity: Java EnterpriseCommunity: Java Web Services and XML Community: JavaDesktop JavaOne Archives
May 2008 Recent EntriesJavaOne - Extending Swing: Creating your own components Securing the integrity and authenticity of links Help? Yes, you can use JavaHelp! | ||||||||||||||||||||||||||||||||||||||||||||
|
|