Editor's note: This is the sixth article in a seven-part series by Chetan Conikee.
In my previous post we witnessed how a flawed design pattern of session management across SaaS vendors led for an exploit to manifest.
Type your email here https://haveibeenpwned.com/ and verify if you have been pwned. If not, skip this entire post.
An Example: Houzz Hack
Houzz, a $4 billion-valued home improvement startup, recently admitted that their data has been breached.
In their FAQ, the company said it “recently learned that a file containing some of our user data was obtained by an unauthorized third party.”
It added: “We immediately launched an investigation and engaged with a leading forensics firm to assist in our investigation, containment, and remediation efforts.”
Houzz said that usernames and scrambled passwords were also taken.
They also said that the passwords were scrambled and salted using a one-wayhashing algorithm, but did not provide specifics on what kind of hashing algorithm was used.
Some would argue that this incident cannot be quantified as a business logic flaw. However, if user passwords were stored securely using a hash function that is specifically designed for passwords and in addition if they are also designed to be slow, a hacker will not be able to takeover breached accounts.
What do we mean by slow?
Let’s attempt to answer these question starting with a worse case scenario
Case #1: Storing clear text passwords in database
UserName : firstname.lastname@example.org
In an event of a data breach, a hacker will be able to log in with your credentials effortlessly. Even worse, you might be using the same password across several other merchants.
If you are think this is unreal, read this — Sony.
Case #2: SHA1(password) or MD5(password)
In an event of a data breach, hackers could employ speed hashing and try billions of combinations in less than a second under 1 CPU hour.
Although dated, Hackers still maintain rainbow table caches. Obviously more complex your password the more safer you are. Statistically, majority of us use our sons, daughters, spouses name and birth date in our passwords.
If you are think this is unreal, read this — LinkedIn.
Case #3: SHA1(FIXED_SALT + password)
Password: SHA1(“my_org_fixed_salt” + password)
The FIXED_SALT can be a long random string of bytes store in a separate secure persistent vault. This will make it much more difficult for the hacker to guess the passwords because they would also need to know the salt.
If the hacker managed to laterally move and compromise your asset, what could stop him/her from gaining access to this fixed salt?
- Is the salt accessed in a secure way from your application?
- Is the salt transmitted over secure RPC channels in your east west microservice mesh?
- Is the salt mistakenly being logged to a log aggregator dashboard?
Adding a FIXED_SALT isn’t still good enough. Let’s move on.
Case #4: SHA1(PER_USER_SALT + password)
Password: SHA1(“per_user_salt” + password)
The next step is to now create a PER_USER_SALT in this secure vault.
Some of the same issues hold as the previous case with FIXED_SALT.
So, if you have 10,000 users, having a per-user-salt makes it 10,000 times harder to figure out the passwords of all your users. Instead of 1 cpu-hour, now they need 10,000 cpu-hours and it’s not expensive to rent compute instances over AWS, Azure or Digital Ocean.
Long story short, still not good enough. Let’s move on.
Case #5: BCRYPT(password)
BCRYPT was specifically designed for passwords. In addition to being secure “one-way” hash functions, it was also designed to be slow.
Read the paper for more details.
If a hacker wants to compute BCRYPT against a list of a billion likely passwords, it will take about 30,000 cpu-hours — and that’s for just a single password.
My final post will look at one more business logic flaw...