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.26.2009
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
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
Pretty simple and straight forward if I had to say so myself. Next we will create our management object, the UserCacheManager.
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
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:
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.
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.
MapuserCache;
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;
ListinitialServers = 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!
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
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!
Labels:
java,
jconsole,
jmx,
management
Subscribe to:
Posts (Atom)