Monthly Archives: January 2016

Sharing with Social Media

Does your application provide a way for users to share their progress or success with others through social media? Are you thinking about adding that feature in the future? Everyone loves to share their stories with their friends and colleagues, but as application developers we need to make sure that we are considering the security aspects of how we go about that.

Take-Aways


  • Use the APIs when talking to another service
  • Don’t accept credentials to other systems out of your control
  • Check with security to validate that your design is ok

This morning, whether true or not (I have not registered for the RSA conference), there was lots of talk about the RSA registration page offering to post a message to your twitter account regarding you going to the RSA conference. Here is a story about it. The page asks for your twitter username and password to then post a message out on your twitter account. Unfortunately, that is the wrong way to request access to post to a social media account.

Unfortunately, even if you have the best intentions, this is going to come across in a negative way. People will start assuming you are storing that information, that you know have access to important peoples twitter accounts going forward. Maybe you do, maybe you don’t, the problem there is that no one knows what happened with that information.

Just about every social media site out there has APIs available and support some oAuth or other authorization mechanism to perform this type of task. By using the proper channel, the user would be redirected to the social media site (Twitter in this instance) and after authenticating there, would provide authorization for the other site to post messages as the registered user.

Using this technique, the user doesn’t have to give the initial application their social media password, instead they get a token they can use to make the post. The token may have a limited lifetime, can be revoked, and doesn’t provide full access to the account. Most likely, the token would only allow access to post a message. It would not provide access to modify account settings or anything else.

If you are looking to integrate or share with social media sites, take the time to determine the right way to do it. This is really important when it involves access to someone else account. Protect the user and yourself. Don’t just take the easy way out and throw a form on the screen. Understand the architecture of the system and the security that needs to be in place. There are a lot of sites that allow sharing with social media, understand how they are doing it. When in doubt, run this by someone else to see if what you are planning on doing looks like the right way to do it.

Password Storage Overview

Start reading the news and you are bound to read about another data breach involving user credentials. Whether you get any details about how the passwords (that were stolen) were stored, we can assume that in many of these cases that they were not well protected. Maybe they were stored in clear text (no, it can’t be true), or use weak hashes. Passwords hold the key to our access to most applications. What are you doing to help protect them?

First, lets just start with recommending that the users don’t re-use their passwords, ever. Don’t share them across applications, just don’t. Pick a password manager or some other mechanism to allow unique passwords for each application. That doesn’t mean using summer2015 for one site and summer2016 for another. Don’t have them relatable in any way.

Now that we have that out of the way, how can the applications better protect their passwords? Lets look at the storage options:

  • Clear Text
  • Encrypted
  • Hashed

Clear Text

While this may seem harmless, since the data is stored in your highly secured, super secret database, it is looked down upon. As a developer, it may seem easy, throwing a prototype together to have the password in plain text. You don’t have to worry if your storage algorithm is working properly, or if you forget your password as you are building up the feature set. It is right there in the database. While convenience may be there, this is just a bad idea. Remember that passwords should only be known by the user that created it. They should also not be shared. Take an unauthorized breach out of the picture for a moment, the password could still be viewed by certain admins of the system or database administrators. Bring a breach back into the picture, now the passwords can be easily seen by anyone with no effort. There are no excuses for storing passwords as plain text. By now, you should know better.

Encrypted

Another option commonly seen is the use of reversible encryption. With encryption, the data is unreadable, but with the right keys, it is possible to read the actual data. In this case, the real password. The encryption algorithm used can make a difference on how long it takes to reverse it if it falls into the wrong hands. Like the clear text storage, the passwords are still left exposed to certain individuals that have access to the encrypt/decrypt routines. There shouldn’t be a need to ever see the plain text version of the password again, so why store it so that it can be decrypted? Again, not recommended for strong, secure password storage.

Hashing

Hashing is process of transforming the data so that it is un-readable and not reversible. Unlike when the data is encrypted, a hashed password cannot be transformed back to the original value. To crack a hashed password you would typically run password guesses through the same hashing algorithm looking for the same result. If you find a plaintext value that creates the same hash, then you have found the password.

Depending on the hashing algorithm you use, it can be easy or very difficult to identify the password. Using MD5 with no salt is typically very easy to crack. Using a strong salt and SHA-512 may be a lot harder to crack. Using PBKDF or bcrypt, which include work factors, can be extremely difficult to crack. As you can see, not all hashing algorithms are created equally.

The Salt

The salt, mentioned earlier, is an important factor in hashing passwords to create uniqueness. First, a unique, randomly generated salt will make sure that if two users have the same password, they will not have the same hash. The salt is appended to the password, to basically create a new password, before the data is hashed. Second, a unique salt makes it more difficult for people cracking passwords because they have to regenerate hashes for all their password lists now using a new salt for each user. Generating a database of hashes based on a dictionary of passwords is known as creating a rainbow table. Makes for quicker lookups of hashes. The unique salt negates the rainbow table already generated and requires creating a new one (which can cost a lot of time).

The salt should be unique for each user, randomly generated, and of sufficient length.

The Algorithm

As I mentioned earlier, using MD5, probably not a good idea. Take the time to do some research on hashing algorithms to see which ones have collision issues or have been considered weak. SHA256 or SHA512 are better choices, obviously going with the strongest first if it is supported. As time goes on and computers get faster, algorithms start to weaken. Do your research.

Work Factor
The new standard being implemented and recommended is adding not only a salt, but a work factor to the process of hashing the password. This is done currently by using PBKDF, BCRYPT, or SCRYPT. The work factor slows the process of the hashing down. Keep in mind that hashing algorithms are fast by nature. In the example of PBKDF, iterations are added. That means that instead of just appending a salt to the password and hashing it once, it gets hashed 1,000 or 10,000 times. These iterations increase the work factor and can slow down the ability for an attacker to loop through millions of potential passwords. When comparing BCRYPT to SCRYPT, the big difference is where the work factor is. For BCRYPT, the work factor effects the CPU. For SCRYPT, the work factor is memory based.

Moving forward, you will start to see a lot more of PBKDF, BCRYPT and SCRYPT for password storage. If you are implementing these, test them out with different work factors to see what works for your environment. If 10,000 iterations is too slow on the login page, try decreasing it a little. Keep in mind that comparing a hash to verify a user’s credentials should not be happening very often, so the hit is typically on initial login only.

Conclusion

Password storage is very important in any application. Take a moment to look at how you are doing this in your apps and spread the word to help educate others on more secure ways of storing passwords. Not only could storing them incorrectly be embarrassing or harmful if they are breached, it could lead to issues with different regulatory requirements out there. For more information on storing passwords, check out OWASP’s Password Storage Cheat Sheet.

Keep in mind that if users use very common passwords, even with a strong algorithm, they can be cracked rather quickly. This is because a list of common passwords will be tried first. Creating the hash of the top 1000 passwords won’t take nearly as long as a list of a million or billion passwords.

Unsupported Browser Support

Ok, so the title is a bit counter-intuitive. I recently saw an article talking about the end of support for some of the Internet Explorer versions out there (http://www.computerworld.com/article/3018786/web-browsers/last-chance-to-upgrade-ie-or-switch-browsers-as-microsofts-mandate-looms.html) and got to thinking about the number of sites that still require supporting some of these older versions of browsers. This is typically more common in the big corporate enterprises, as they have the legacy systems and tend to move slower upgrading internal software.

The unfortunate reality is that, in some environments, you are stuck supporting outdated browsers. Whether it is an internal application with requirements for the network, or your client base is just slow to move on. This requirement also puts those users, and potentially the company network at risk since there are no more security updates for these browsers.

Over the past few years, browsers have been taking on some of the burden of stopping some forms of application security attack vectors. We saw the addition of the cross-site scripting filters added a while back to help detect and neutralize some reflective cross-site scripting attacks. We also saw browsers start to support custom response headers to indicate content security policy, frame handling, etc.. Some of these protections are supported across all browsers, while others are limited to specific browsers, or versions of browsers. As we see these unsupported browsers still out there, it reminds us that as developers, we cannot rely just on browser functionality for security.

While we may not be able to control what version of a browser we support, well we can but we can’t, we can still make sure that our application is as secure as possible. Lets take cross-site scripting as an example. Sure, for reflected XSS, we could just sent the X-XSS-Protection response header and hope for the best. It might neutralize a few instances, but that is a pretty poor defense mechanism. First, there have been numerous bypasses for these types of client-side blocking attempts. Second, it is our responsibility, as developers, to properly handle our data. That starts with good input validation and ends with properly encoding that data before we send it to the browser.

I am not advocating not using the different response headers. Bugs can be missed and having another control there to help reduce the chance of a vulnerability being exploited is a good thing. But the first effort should be spent on making sure the output is encoded properly in the first place. This is where testing comes into play as well, making sure that we are validating that the encoding is working as expected.

By properly protecting our apps with good application security practices, it shouldn’t matter what browser the client is using. Does the end user run a higher risk, in general, by running out of date software. You bet. That doesn’t mean our application has to be the source of that added risk.

If you are stuck supporting out dated browsers due to corporate compliance or other reasons, take the time to analyze the situation. Determine why that browser is needed and what possible solutions are there. Raise the issue up within the organization, identifying the risks that are exposed due to the use of outdated browsers. While the organization may already know this, it doesn’t hurt to say it again.