Thursday, May 31, 2012

Best Practices while dealing with Password in Java

While working in core Java application or enterprise web application there is always a need of working with passwords in order to authenticate user. Passwords are very sensitive information like Social Security Number(SSN) and if you are working with real human data like in online banking portal or online health portal its important to follow best practices to deal with passwords or Social security numbers. here I will list down some of the points I learned and take care while doing authentication and authorization or working with password. I recommend to read more on this topic and have a checklist of things based on your application requirement. Anyway here are few points which make sense to me:

7 Tips to deal with sensitive information or password in Java

1) Use SSL to transfer username and password:
LDAP and Active Directory are mostly used for storing username, password, authorities and access and has become standard in almost all places, but doing LDAP authentication is still a programming task and you need to collect and pass passwords from user to LDAP Server securely. Use SSL while doing LDAP bind operation otherwise anyone can
intercept LDAP  traffic and get access to username and password. Spring security offers a convenient way of doing
LDAP authentication. see my post how to perform LDAP authentication in Java using spring security for more details.

2) Store password in char[] instead of String
Strings are immutable in Java and there is no way you can erase content of String because any modification in String
will result in a new String. Also Strings are cached in String pool which pose a security risk of exposing password in clear text to anyone who has access to memory of java application. even an accident like core dump of java application, generating memory dump in /tmp can put passwords in real threat. by using char[] you can erase convents by setting it blank or any other character which reduces security risk of exposing password. See Why char array is better than String for storing password in Java for more detail

3) Always use encrypted password in Application
This is one step further from earlier tip, instead of Storing password or sensitive information in clear text always store them in encrypted or hashed format. This reduces risk of exposing password to any stranger who some how has access of application memory while you are performing authentication.

4) Clear password or sensitive information as soon as possible
Never left your password unattended or longer than needed, erase it as soon as you are done with them. Also caching password or storing them for future checks is not a good idea. Its recommended to keep password or any sensitive data like SSN for very short duration in memory or heap.

5)Don't cache Passwords
As I said earlier never cache a password for future authentication or any kind of checks. authenticate it once and clear the password if needed do a re authentication in similar fashion.

6) Use control to hide password while entering in user interface
Always use JPasswordFiled or similar control like input type=password in html forms for asking password
from user to avoid risk of anyone seeing it while entering or to prevent from any peeping tom.

7) Never pass sensitive information like passwords, SSN to logger, on Exceptions or to console.
Exceptions are real risk since sometime they print data associated with Error like FileNotFoundException may print name of file if not found, In order to tackle this issues always cache primitive Exception and sanitize it before re throwing it or delegating it for further processing especially while writing code which requires stringent security.

best practices to deal with sensitive information in Java passwords, SSNThat's all on best practices of dealing password in Java application. In my opinion these are just tip of iceberg in most of enterprise application standards are even more stringent and a proprietary guideline to deal with passwords may exist. I still see value of these common points because it help to mitigate risk associated with sensitive data. Please let us know what best practices you are following while working with passwords in Java or J2EE application.

If you are new here you may like to check these older Java posts


Further Reading
Understanding the Java Virtual Machine: Security
Iron Clad Java: Building Secure Web Application
Java Performance The Definitive Guide

P.S. - If you are an experienced Java/JEE Program and want to learn Spring Security end-to-end, I recommend Learn Spring Security course by Eugen Paraschiv, The definitive guide to secure your Java application. It's useful for both junior and experienced Java Web developers.

He is also author of REST with Spring course, one of the best online course to learn RESTful WebServices using Spring framework.

P.S - If you like to learn from book, then Pro Spring Security by Carlo Scarioni is a good starting point. The content is not advanced enough for senior developers but for junior and intermediate programmer, it's a great book.


atc said...

Passwords should NOT be encrypted but in fact hashed using bcrypt + a per-password salt. Please amend this, it's bad advice!

Javin @ ldap authentication using spring security said...

@atc, Indeed password should be hashed and salted and most of Security framework like Spring Security supports this, point there was to atleast keep them encrypted instead of clear text. Thanks for asserting the need of hashed + salted password.

Craig said...

2) Store password in char[] instead of String

This is (IMHO) a bad idea for a few reasons:

1. That's going to massively complicate things. Strings maintain information about character encodings - char[] (obviously) does not. So if you use char[], you have to be very careful to always use the same encoding. This is critical if you support non-US English users (and you should always do that!).

2. If a malicious user gets access to read core dump files in /tmp, it's game over anyways. At that point, it means that not only has a malicious user gained access to your server, but he's also gained either root or application user access - so he's fully compromised the system.

3. char[] are not pinned to RAM. The OS swaps char[] data just as easily as String data, writing it to disk in the swap file.

4. Strings may be immutable, making it more likely that they hang around for a while in memory due to string internment, but char[]'s aren't guaranteed to be removed from memory either due to the uncertainties of garbage collections. You can never be sure any memory is cleared in Java, nor can you tell Java to clear any memory.

Using char[] instead of String makes your code buggier, harder to maintain, harder to write, and only more secure in a totally impractical sense.

Fareez Ahamed said...

Hi Javin,

I came up with an idea sometime back. By using encrption. Check it out and give me your suggestion.


Richard Hash said...

So how do you get around using java.sql DriverManager or Driver? The APIs require a String object, which means at least once you'll have to convert your char[] to a String, and once you've done that, it's immutable, it's in memory, you can't overwrite it, and you are hosed....

Javin @ transient vs volatile said...

Hi Richard, you bring valid point, Its not always possible.It depends upon information for SSN and passwords you got to be more secure than application specific details like JDBC passwords you can afford that, but having a naked password in config file is bad, rather you should have encrypted password there.

Richard Hash said...

This is where something like .NET's SecureString might be useful in Java....

Post a Comment