6.26.2009

State of the InterWebz - Authentication and Usability

I am going to divert away from my current JMX saga for a brief moment to discuss an interesting post on the internet that was shared with me regarding usability versus security with masked passwords.

The post, from Jakob Nielsen, states that it is time to do away with password masking to improve usability (post is referenced at the bottom of this post).

This got some interesting conversation going on the webappsec mailing list and got me to thinking about the problem. Jakob has a point in his original post, that as a result of password masking, the average user tends to choose simple passwords to remember (which are quick and easy dictionary cracks) especially if they plan on logging on to the website from their mobile device.

I am sure everyone is aware why password's are masked in just about every type of password type authentication medium across the globe (ie: website logins, OS login, ATM PIN, Alarm Code, etc.) but the main goal is to prevent "shoulder surfers" from easily learning peoples passwords. Arguably, this is a first line of defense only, and not even close to a solution as someone who is good at their craft will be able to get your password just as easily by watching you type it on the keyboard. There are also several other ways that a devious individual may gain access to your password with keyloggers, camera's, or good old fashioned social engineering and simple masking your password bears no protection against these types of recon.

Now don't get me wrong, I am of the mind that having your password masked is a good thing, if we continue to rely on password type authentication. Any security concept should be multi-layered to address as many concerns as possible.

On the iPhone, when you type in a password, it apparently shows the current character you are typing in the form field, then masks it when you move on to the next character. This is an interesting concept and one that has apparantly been adapted on some sites across the internet using a JavaScript hack on a normal form input field.

I am definitely not of the opinion that this is a good idea by any means. Password masking is something that happens at the browser level. A developer simply specifies that a field on a form is of type password, and the browser implements a masking strategy over that field. JavaScript has no place in the security realm, regardless of how harmless it may seem, most of the time when you introduce javascript as a security tool, you open more holes than you close due to the nature of the language and how it interacts with browsers.

This brings me to the point of this post.

We live in a world where every day we grow more and more reliant on the internet to go about our daily lives. We bank online, we shop online, we interact and communicate online, there isn't much that we cannot and in most cases *don't* do online.

The world was a much more seemingly innocent place when the internet was born and no one envisioned that it would be what it is today, and as such, the security model that the internet uses is far too lax to be reliable, no matter how many layers of hacks and crap we put in front of it. There will always be one significant security hole on every web application in the world, in every social network, and on every bank or shopping site.

Humans as a Vulnerability

No matter what we do, the human element will always be there and the average human being has no idea what dangers are lurking around every click he makes on the net. There are a ton of plugins and apps that help to mitigate the risks of using the internet like popup blockers, phishing filters, virus scanners, and so on. These are essential to have installed in any environment, but they do not solve the problem of a poor security model overall, they only patch little leaks in a sinking boat.

Browser manufacturers need to go back to the drawing board when it comes to security and especially when it comes to authentication.

I don't pretend to have all the answers, if I did know the answer, I would be a rich man. I do have thoughts and theories though.

Certificates

Certificates eliminate the need for any human interaction in the authentication space. This, generally, is a good thing provided the human involved can keep his certificates safe. The main problem with using certificates is that support for them in the web space at this point, is shaky at best and there is no good implementation model to use them for authentication to web applications that I have seen. I feel that using certificates is probably the best option that we have in today's world as a first line of defense in our applications when it comes to authenticating users and verifying their identity.

Certificates themselves can also have a password to use, or an empty password for passwordless use. So if you are using a certificate to authenticate and you don't have a password set on the certificate itself, someone only needs gain access to your certificate files to become you.

Password Vaults

Password vaults are a great idea for people who need to remember a lot of passwords. I personally have solved the complex password typing issue completely on my blackberry by using it's integrated password vault to manage all my different internet passwords on different sites. The idea behind a password vault is that you only need remember one password, the password to your vault. The vault stores all of your individual passwords (encrypted of course) and sends them to the application when it prompts you for your password. This is a pretty ingenious idea that has been around for quite some time, however it too has it's vulnerabilities.

Your passwords are stored in a file, usually in some type of proprietary encrypted format specific to the password vault application that you are using. And they are of course, protected by a password. If a nefarious individual determined what password vault you were using, and in turn acquired, through some questionable means, your data file and your password (see shoulder surfing, key logging, etc) they could potentially unlock every password to every application you use and thus, become you.

Fingerprinting

Fingerprinting is an interesting concept that covers a wide variety of authentication in the real world. From retinal scanners, to fingerprint scanners, to hardware addresses and device fingerprinting, this is an interesting yet still vulnerable means of authentication.

For example, a good friend of mine bought an HP laptop with a fingerprint scanner and a touch screen. Hmmm. Sounds too easy to me. I quickly was able to demonstrate how in less than a minute I could lift a fingerprint from his monitor, and use it to gain access to his laptop.

We've all seen in the movies when the guy wears contacts fashioned to look like someone else eye bypasses retinal scanning, and while that may be science fiction in most regards, with todays technology it is very possible to create if you have know the right people and they have the right equipment.

Hardware addresses and device fingerprinting are all-to-easy to bypass these days. Wireless access points have shown us how quickly and easy it is to become another device altogether through some quick air sniffing.

So whats the answer?

My theory is that all of the above should be combined, to create a multi-layered authentication engine that is capable of thwarting most would be attackers, or at least making their job a good deal more difficult and time consuming.

What if there was a browser that implemented a secure password vault (I am not talking about the 'Remember This Password' popup that browsers currently have, I am talking about a true password vault with strong encryption). Having a single password to unlock every password would encourage people to put more thought into creating a more complex password that would be much more difficult to crack. When you only need to remember a single password, it is much easier to remember a complex one. Since all interaction with the applications would be handled via the password vault, the actual application passwords could be extremely complex sequences generated randomly by the password vault itself. This would require application developers to change their line of thinking too, and implement a new type of signup functionality and authentication strategy. Perhaps password creation and authentication would happen as a seperate request over a https connection that would create a token on either side of the connection for challenge/response authentication per-request. But I digress..

Now let's take it to the next step. This is where certificates come in. Instead of unlocking the password vault with a password, what if the password vault was unlocked with a certificate. For the end user, if using a password secured certificate this really is a transparent feature to them, as they still enter a single password to unlock every password, however, it adds an additional layer of complexity to the nefarious hackers evil plot to become you. Now in addition to getting your password vault data files, they also have to acquire your private key to unlock the vault.

Already, we have not only improved the usability of authentication on the web, we have easily doubled or tripled the complexity that a hacker must overcome to steal your identity on the web, just by leveraging existing technologies in a way that makes sense for the security model. This is probably good enough, but I am going to take it even one step further, given the nature of what people do on the internet every day, I would like to see something even more secure.

This is where device fingerprinting comes into play. A USB key could be the answer to the problem of human interaction. A lot of people will immediately argue at this point that now authentication on a website requires a physical piece of hardware to be on your person at the point in time which you wish to use the service. This is where I say, yes, precisely.

Think about it this way, most of us live in a house or apartment; and we safeguard our belongings, information, and family by putting a door that locks and requires a key to unlock between ourselves and any would-be intruders. Granted, there are other ways into a house, just as their are other means to steal an identity on the internet, but if a thief had the choice of walking through an unlocked door or breaking a window, which do you think he would choose?

My concept is that browser manufacturers include a means for an end-user to generate a signed certificate, that is a certificate signed by the browser manufacturer itself, that's single purpose is to live on removable storage (ie: USB thumb drives) and unlock their password vault. The end user then slides the USB thumb drive onto their key ring right between their car keys and the key to their deadbolt on their house and voila! Unless you have a habit of leaving the house without your car keys you will most likely have your authentication with you at all times.

Now, I will be the first to admit, this all seems like it would be far too much for say signing on to facebook, however, think about signing on to your bank website, or purchasing items online, or trading stock, updating insurance information, or filing taxes. All these things are sensitive operations that I believe require a great deal more authentication and proof of identity on the web than typing bob303 into a password box on a web form.

Security constraints should always reflect the level of sensitivity of the action that you are trying to take and it should be no more different on the internet. The responsibility lies on the browser manufacturers, the server developers, and the application developers to recognize this and implement something new. I am sure that there are holes in my concept and there are definately ways around it if an application has vulnerabilities outside of it's authentication scheme (ie: session hijacking, cross-site request forgery, etc.) but your authentication is your first line of defense and as such it should be treated with a great deal more respect than it currently is.

I could probably continue on about this for another 50 pages, and perhaps I will have to write a paper detailing my ideas and theories about the general state of security on the web and the mindset of the people that create functionality therein, but for now I think this brings up some interesting topics for debate and conversation and I am anxious to hear other peoples thoughts.

References:

Jakob Nielsen's post on Password Masking versus Usability
http://www.useit.com/alertbox/passwords.html

WebAppSec Consortium (Home of the Web Security mailing list)
http://www.webappsec.org

6.17.2009

JMX Management for fun and profit - Act 2

So now that we have caused an ample amount of trouble with our App Servers messing around with all those internal MBeans, stopping servers, etc.; I think it is time to move on to Act 2, in which our hero creates a custom MBean!

This is where things start to get interesting. Let's say for arguments sake, that you have a cache that you would like to be able to invalidate from anywhere. This will be the premise for our first custom MBean.

Our first order of business is to create our "Cache" object that we want to manage. Normally this would exist already, however, for the sake of education, I will create one here first.

UserCache.java

package mbeans;

/**
* Before you all go crazy about this should be a singleton and it is not threadsafe,
* let me just point out that this is for all intents and purposes a "mock-object"
* designed to prove a point. That is all.
*/
public class UserCache {
// For simplicity, I will make this package-private so the management wrapper
// can access it easily.
Map userCache;

public UserCache() {
this.userCache = new HashMap();
}

public User getUser(String username) {
User u = userCache.get(username);
if ( u == null ) {
u = UserDaoFactory.getUserDao().loadUser(username);
userCache.put(username, u);
}
return u;
}
}


The next step is to create our MBean Interface. JMX Spec says that an MBean interface and implementation should follow a strict naming convention where the MBean interface is the managed objects name followed by MBean. So for our example, we are going to create a Manager object called UserCacheManager, thus, our interface shall be named (in the same package) UserCacheManagerMBean.

Let's take a look at our MBean interface.

UserCacheManagerMBean.java

package mbeans;

public interface UserCacheManagerMBean {
void invalidateCache();
}


Pretty simple and straight forward if I had to say so myself. Next we will create our management object, the UserCacheManager.


package mbeans;

public class UserCacheManager implements UserCacheManagerMBean {
private UserCache managedCache;

public UserCacheManager(UserCache managedCache) {
this.managedCache = managedCache;
}

public void invalidateCache() {
managedCache.userCache = new HashMap();
}
}


So far, so good. The only thing we have left to do is register it with our MBeanServer. If you are running an application server, you can just about guarantee that one has already been created and has a ton of beans registered in it already. Bearing that in mind, let's count on that for the purpose of this example and register our mbean with the default server.

This next class will act as the Factory object for getting a UserCache, and will be the point of entry from our entire program, so we will let it handle the registering of the management object.

UserCacheFactory.java

package mbeans;

public class UserCacheFactory {
private static final UserCacheFactory instance = new UserCacheFactory();
public static UserCacheFactory getInstance() { return instance; }

private UserCache userCache;

public synchronized UserCache getUserCache() {
if ( userCache == null ) {
userCache = new UserCache();
registerManagedCache();
}
return userCache;
}

private registerManagedCache() {
MBeanServer server = null;

List initialServers = MBeanServerFactory.findMBeanServer(null);
if ( initialServers != null && initialServers.size() > 0 ) {
server = initialServers.get(0);
}

if ( server == null ) {
server = MBeanServerFactory.createMBeanServer();
}

try {
ObjectName mbeanName = new ObjectName("Application:impl=UserCacheManager");
server.registerMBean( managedCache, mbeanName );
catch (Throwable t) {
t.printStackTrace();
}
}


Let's look at what we are doing in the above code.

First off, we made it a little more threadsafe with a singleton factory that has a synchronized getUserCache() method.

Second, if we are constructing a new UserCache when we access it from the factory, we also create the manager bean for the class at the same time and register it with the MBeanServer.

Let's take a second to talk about this mysterious new ObjectName object that I am creating for this MBean.

ObjectName is an object that represents the namespace that a bean will live in once it is registered with the MBeanServer. This is how any clients or agents will know of this MBean. The namespacing is made up of two main parts, delimited by a colon. The first part is the Domain in which the MBean lives - This should be somewhat specific to your application. The second part of the ObjectName string is a set of key=val pairs delimited by commas. For example, key1=val1,key2=val2.

If you were to browse in jConsole for our new UserCacheManager, you would find it listed under:

+ Application
+ UserCacheManager


If you were to lookup the MBean by it's name you would look it up using the same string that we passed into the ObjectName constructor.

Voila! We have created our first custom MBean and have registered it with our default MBeanServer instance. If you run this code in your App Server, you should be able to connect to the server's JMX port with jConsole and see the manager object appear in the MBeans tab shortly after you access the method UserCacheFactory.getInstance().getUserCache() for the first time in your application.

Stay tuned in Act 3 as we explore the different types of MBeans that you can create aside from the above demonstrated standard MBean. We will look at MXBeans, Open MBeans, Dynamic MBeans, and Model MBeans; see examples of each; and determine the positives and negatives of using each type.



6.14.2009

JMX Management for fun and profit!

I have recently been tasked with the project at work to start implementing JMX to manage our production app servers. Prior to this I had heard of JMX and knew a little about what it was and it's overall purpose, but there was a great deal that I didn't understand going into the project and over the last few monthes I have learned a great deal, not only about JMX but also about Management Architecture and Systems in general.

We have, what I would refer to, as a fairly common production system architecture. We have multiple applications that run over multiple clusters of tomcat servers. Some of our production servers run clusters of tomcat servers themselves as well, which presents a whole new layer of problems.

Basically, step 1 was to implement JMX and custom MBeans into our application. I started with some low hanging fruit. Our local application cache has always been a problem child so it was a good place to 'test the waters' and see what JMX could do for us.

I should also note that this is still an ongoing project so I will also be periodically updating this blog with new things that I implement as the project matures and eventually becomes a reality.

The first step in this long ardous journey was to get JMX up and running in our app servers so that we could connect through JConsole and get access to our MBeans as we created them.

A little googling showed that this is pretty simple to do with just some command line parameters passed into the JVM.

-Dcom.sun.management.jmxremote

Setting this system property registers the JVM Instrumentation MBeans and publishes an RMI connector to allow JMX Client applications to connect to it from the same physical machine.

Close, but not quite there, I want to be to connect to the server from a different machine. So there are a few more things I need to set in the JVM to allow this.

-Dcom.sun.management.jmxremote.port=
-Dcom.sub.management.jmxremote.authenticate=false

Nice! Setting this property exposes the RMI Service on so you can connect to it remotely.

Now I can connect remotely, however, anyone else with JConsole can also connect remotely and do lots of nastiness to the server. We don't want that!

-Dcom.sun.management.jmxremote.password.file=
-Dcom.sun.management.jmxremote.access.file=

As you can probably guess, this sets the path's to a couple of files that the RMI Service will use to authenticate connections. An example of each is provided with the JDK in $JRE_HOME/lib/management.

NOTE: There is a security risk in using this form of authentication for JMX. The username and password values are sent to the server in cleartext, thus anyone sniffing packets could intercept the authentication credentials and connect to your server. That being said, if your servers are behind a firewall and you are only connecting from inside your corporate network, this may not be an issue for you, however, the safest way to go would be to use SSL Authentication with certificates to authenticate connections to your RMI Service. I will cover using SSL Certificates in a subsequent blog entry.

Awesome! I can now connect to my JMX Managed Tomcat Server from another machine and do all kinds of fun stuff to my JVM and Tomcat instance.

To connect, I simply open JConsole from a PC that has the JDK installed on it and open a connection to my remote server. In Java 6 (which has a far better version of jconsole) select Remote Process and the address and port of the server you want to connect to, as well as the username and password specified in your jmxremote.passwd file.

For example:
Remote Process: 192.168.0.100:9100 Username: Manager Password: s3cr3t

Viola!

In my next post I will cover creating custom MBeans and different things you can do with your own MBeans to make managing your small to enterprise application easy and fun!

5.30.2009

SQL Injection... Still? Really?

When it comes to development blunders there is one thing that really just rubs me the wrong way, no matter what language I see it in. SQL Injection is that one thing. I can understand XSS bugs, DOS vulnerabilities, buffer and stack overflows, information disclosure bugs, and just about any other type of application vulnerability that you can think of, but really there is just no excuse for the most basic SQL injection bugs to exist anymore.

If you do a google search for SQL Injection, you will see 'Results 1 - 10 of about 2,990,000 for sql injection'

Yes, you did read that correctly.. That really does say 2,990,000 results for SQL Injection. Seeing that should raise a big red flag in your minds eye, a big red flag that says, "Why, oh why is this still an issue?"

Code Injection as a generalized vulnerability is the act of embedding executable code into an application thereby forcing that application to perform an action specified by the user. This is a pretty broad description and really describes anything from a BOF (that's buffer overflow for you non-l33t types) to XSS (Cross Site Scripting) to my favorite SQL Injection.

Let me digress for a second.

The vast majority of websites on the internet are run by one guy in his spare time. Not every site has a Development Team full of Architects, Designers, Security Analysts, QA Analysts, and Database Administrators. That one guy acts as all of those people, and more often than not, doesn't look very good with any of those hats on. That one guy also relies on the 'frameworks' he downloads off of the interwebz to take care of all that tedious difficult stuff for him. Keep that in mind as we move forward along the tracks of my train of thought.

SQL Injection differs from most other types of code injection in that it has the ability to change the persistent state of an application or a site. There are some other forms of code injection that can do the same thing either by themselves or by accessing the persistent storage used by the application in the injected code, but every Skiddie in the world knows about ' or 1=1. Thus, if your app has this:

$badSQL = "Select * from users where username='$_GET['username']' and password='$_GET['password']'"

You end up with:

select * from users where username='Administrator' and password='' or 1=1

Go ahead now and type that into your MySQL Client and see what that returns... Whoops.. If you don't have a MySQL client, well, you'll just have to take my word for it that bad things follow.

I could spend all day (or night in this case) discussing all the different types of SQL Injection attacks, and all the proper ways to combat them; fortunately I don't have to because 2,990,000 pages have already gone down that path according to the mighty Google. That is beyond the scope of this article. What I want to talk about is why this is still happening. Why do we still see hundreds of new sites and apps each year falling victim to something that is so widely known, so easy to take care of in almost any language?

The answer is simple, and is the answer to most questions about things dealing with Application Security. The answer, my friends, is pure and simple HUMAN LAZINESS.

To put it in the simplest possible way, developers, and I use the term loosely, are either too lazy to care about fixing this simple issue, or too lazy to learn that it is an issue.

Option 1: Too lazy to care
This covers a pretty broad scope of excuses and general B.S. that these self proclaimed developers will use. Everything from "I didn't think that my app would get enough exposure to attract hackers." to "There's nothing worth stealing in my application anyways."

For the too lazy to care breed, let me just tell you this. Skiddies love your small website that you built for your bowling league photo album. You know why they love it? They may be skiddies, but even they know that they can completely take over your site and you will never be any the wiser because you are the guy that would never, never, ever expect to have your site pwnt.

Option 2: Too lazy to learn
I think this covers the vast majority of the people who are guilty of belonging to this caste of developer, specifically in the web space. This is the guy that got a PHP for Dummies book for christmas from his wife's brother's dog's former owner, read the first two chapters, and starts up a project on SourceForge for the newest latest greatest web app in the world. You sir, have commited the 8th Deadly Sin - "Thou shalt not distribute code that sucks"

So there it is. This is why SQL Injection has been and is still on the OWASP Top Ten List since 2004 when it was incepted.

In conclusion, I challenge you, blog-o-sphere, developers, humans - to write your next batch of code with input filtering and proper validation, or using parameterized queries (which I believe are available in almost every major interpreted or server-side language there is by now).

I challenge you to get this off of the OWASP Top Ten List for 2010.

I challenge you to overcome the laziness and put time and effort into learning your craft, or walk away and leave it to the people that do. There are plenty of ways you can get your information onto the tubez without ever having to write a single line of code.

While you're at it, I challenge you to share this post with your friends who may or may not fall into one of these categories, your friends who will read this and nod their head in agreement, and your friends who simply like to slashdot and facebook share every single page they come acrossed.

Until our next blog-o-spheric confrontation - may the schwartz be with you, farewell, and thanks for all the fish!