This article will describe how to protect your J2EE application from Insecure Cryptographic Storage issues using ESAPI and other techniques. As with all of the detail articles in this series, if you need a refresher on OWASP or ESAPI, please see the intro article The OWASP Top Ten and ESAPI.
What’s the problem?
First, let me start off by saying Crypto is hard, really hard. There are various aspects to cryptographic security, and all of them are difficult to get right. Some examples include creating an algorithm, using the algorithm and key management. Typically, developers aren’t creating algorithms. That is often done by (really smart PhD) mathematicians, and a small set of developers who implement those algorithms. However, many developers do “use” those algorithms to do some type of encryption in their applications. Developers also have to deal with key management.
Let me additionally state here that I am by no means an expert on this topic. I have some background with crypto, but I certainly don’t have a lot, so much of what’s presented here are generally accepted best practices, and don’t necessarily come from my own experience. OK, on to the detail…
What does Insecure Cryptographic Storage mean? As usual, let’s check in with what OWASP says:
“Protecting sensitive data with cryptography has become a key part of most web applications. Simply failing to encrypt sensitive data is very widespread. Applications that do encrypt frequently contain poorly designed cryptography, either using inappropriate ciphers or making serious mistakes using strong ciphers. These flaws can lead to disclosure of sensitive data and compliance violations. ” [from here]
So, this is pretty self-explanatory. If something can go wrong, it will with crypto. There are lots of reasons why this is probably true. First, it’s hard to get right in the first place – there are a lot of moving parts. Second, developers typically don’t understand it as well as other aspects of software. Third, it’s rare. A small number of people have been dealing with crypto for a long time, but it’s only a relatively recent development that LOTS of devs have been impacted by it. Part of this is due to new regulatory constraints that require encryption of some kind for data at rest.
Where do we go from here? ….
Now that we’ve established that crypto storage is hard, let’s talk about a few common approaches that can help remedy the issues.
1. Stay Educated. This is an important step. Due to the increase in computing power that we gain every year, as well as new cryptanalytic (breaking a crypto algorithm) attacks, the list of “good” algorithms is somewhat of a moving target. Typically, if you’re in the US, NIST (nist.gov) is a good place to check as they set crypto standards. Additionally your workplace may have a set of approved standards that you would need to follow. Also, read books to learn about crypto. You may not be the mathematician coming up with the algorithms, but there is much to learn here that will benefit you.
2. Use good algorithms. This is a follow on to the first point, but it’s important enough to call out separately. Do NOT create your own crypto algorithm unless you’re an expert – it is very difficult to get right. Even the guys at the top of the field tend to create algorithms as part of a team, and those algorithms are generally only accepted as secure after years of analysis by peers. Additionally, do NOT use old, weak algorithms. These could help to a point, but many of them are able to be broken in minutes or even seconds these days. It’s easy enough to use solid algorithms, so educate yourself and make the right choices.
3. Do good key management. This is a broad topic which I don’t even pretend to comprehend fully. There are many possible ways this could work. At the current time, it’s even an active discussion among the ESAPI developers over how they plan to do it. There are various options from just hard-coding a key (DON’T DO IT) all the way up through large commercial systems to do key management for you. Spend some time thinking over your requirements, and make an informed decision.
4. Encrypt credentials. Pretty much every J2EE system connects to a DB, LDAP, web service or some other repository. The credentials to make these connections should be encrypted to prevent easy access to these data storage systems.
5. Don’t store sensitive data if it’s not a requirement. Storing sensitive data is what introduces these complexities. It’s better if you don’t have to worry about them in the first place. Only store sensitive data when there is a firm legal or business requirement.
6. Know your regs. Know your legal and regulatory requirements. There are certain provisions in these requirements that prevent the storage of certain pieces of data EVER. Storing this data not only places additional requirements on your application, it can carry some hefty fines for breaking these laws.
7. Simplify. It’s the old KISS principle. However, when it comes to crypto, it’s certainly true. Do the least you’re required to do in order to store sensitive data securely. The more complex a system, the more difficult it is to secure generally.
8. Store the key/password/data separately. These pieces of information make up your data protection mechanism. Storing them in the same place makes it simpler for an attacker to gain access to all of them. If they are stored separately, an attacker may still gain access to all of them, but it’s more difficult.
9. Use filesystem controls. Operating systems have filesystem access controls for a good reason – so you will use them. Protecting data is a defense in depth task, but protecting the keys, passwords, etc. with filesystem controls locked down so only the appropriate user(s) has access is a best practice measure to help secure your data.
One thing to note here is that I did not add any sample code snippets for this topic. This was intentional. At the moment, the ESAPI encryptor implementation is going through a fairly significant update and code review. There is still some discussion of major changes coming. Either way, ESAPI will provide support to encrypt/decrypt and hash data. The interface to that functionality may change, but the library will provide those features – you can be sure of it.
Well, that’s it. Hope you’ve found this article helpful. Let me know if you have any questions or suggestions.
Other articles in this series:
Part 0: The OWASP Top Ten and ESAPI
Part 1: The OWASP Top Ten and ESAPI – Part 1 – Cross Site Scripting (XSS)
Part 2: The OWASP Top Ten and ESAPI – Part 2 – Injection Flaws
Part 3: The OWASP Top Ten and ESAPI – Part 3 – Malicious File Execution
Part 4: The OWASP Top Ten and ESAPI – Part 4 – Insecure Direct Object Reference
Part 5: The OWASP Top Ten and ESAPI – Part 5 – Cross Site Request Forgery (CSRF)
Part 6: The OWASP Top Ten and ESAPI – Part 6 – Information Leakage and Improper Error Handling
Part 7: The OWASP Top Ten and ESAPI – Part 7 – Broken Authentication and Session Management
Part 8: The OWASP Top Ten and ESAPI – Part 8 – Insecure Cryptographic Storage
Part 9: The OWASP Top Ten and ESAPI – Part 9 – Insecure Communications
Part 10: The OWASP Top Ten and ESAPI – Part 10 – Failure to Restrict URL Access