Popular collaboration tool Slack (not to be confused with the nickname of the world’s longest-running Linux distro, Slackware) has just owned up to a long-running cybersecurity SNAFU.
According to a news bulletin entitled Notice about Slack password resets, the company admitted that it had inadvertently been oversharing personal data “when users created or revoked a shared invitation link for their workspace.”
From 2017-04-17 to 2022-07-17 (we assume both dates are inclusive), Slack said that the data sent to the recipients of such invitations included…
…wait for it…
…the sender’s hashed password.
What went wrong?
Slack’s security advisory doesn’t explain the breach very clearly, saying merely that “[t]his hashed password was not visible to any Slack clients; discovering it required actively monitoring encrypted network traffic coming from Slack’s servers.”
We’re guessing that this translates as follows:
“Most recipients wouldn’t have noticed that the data they received included any hashed password information, because that information, although included in the network packets sent, was never deliberately displayed to them. And because the data was sent over a TLS connection, eavesdroppers wouldn’t have been able to sniff it out along the way, because it wouldn’t get decrypted until it reached the other end of the connection.”
That’s the good news.
But network packets often include data that’s never normally used or seen by recipients.
HTTP headers are a good example of this, given that they’re meant to be instructions to your browser, not data for display in the web page you’re looking at.
And data that’s irrelevant or invisible to users often ends up in logs anyway, especially in firewall logs, where it could be preserved indefinitely.
That’s the bad news.
Salt, hash and stretch…
According to Slack, the leaked data was not merely hashed, but salted too, meaning that each user’s password was first mixed together with random data unique to that user before the hash function was applied.
Hashes are essentially “non-reversible” mathematical functions that are easy to calculate in one direction, but not in the other.
For example, it’s easy to calculate that:
SHA256("DUCK") = 7FB376..DEAD4B3AF008
But the only way to work “backwards” from 7FB376..DEAD4B3AF008
to DUCK
is to work forwards from every possible word in the dictionary and see if any of them come out with the value you’re trying to match:
SHA256("AARDVARK") = 5A9394..467731D0526A [X] SHA256("AARON") = C4DDDE..12E4CFE7B4FD [X] SHA256("ABACUS") = BEDDD8..1FE4DE25AAD7 [X] . . . 3400 skipped SHA256("BABBLE") = 70E837..CEAD4B1FA777 [X] SHA256("BADGER") = 946D0D..7B3073C1C094 [X] SHA256("BAGPIPE") = 359DBE..BE193FCCB111 [X] . . . 3200 skipped SHA256("CABAL") = D78CF4..85BE02967565 [X] SHA256("CACHE") = C118F9..22F3269E7B32 [X] SHA256("CAGOULE") = 5EA530..5A26C5B56DCF [X] . . . 5400 skipped SHA256("DAB") = BBCC8E..E8B98CAB5128 [X] SHA256("DAFFODIL") = 75121D..D6401AB24A98 [X] SHA256("DANGER") = 0BD727..4C86037BB065 [X] . . . 3500 skipped SHA256("DUCK") = 7FB376..DEAD4B3AF008 [FOUND!]
And by including a per-user salt, which doesn’t need to be secret, merely unique to each user, you ensure that even if two users choose the same password, they won’t end up with the same password hash.
You can see the effect of salting here, when we hash the word DUCK
with three different prefixes:
SHA256("RANDOM1-DUCK") = E355DB..349E669BB9A2 SHA256("RANDOM2-DUCK") = 13D538..FEA0DC6DBB5C <-- Changing just one input byte produces a wildly different hash SHA256("ARXXQ3H-DUCK") = 52AD92..544208A19449
This also means that attackers can’t create a precomputed list of likely hashes, or create a table of partial hash calculations, known as as a rainbow table, that can accelerate hash checking. (They’d need a brand new hashlist, or a unique set of rainbow tables, for every possible salt.)
In other words, hashed-and-salted passwords can’t trivially be cracked to recover the original input, especially if the the original password was complex and randomly chosen.
What Slack didn’t say is whether they’d stretched the password hashes, too, and if so, how.
Stretching is a jargon term that means repeating the password hashing process over and over again, for example, 100,000 times, in order to extend the time needed to try out a bunch of dictionary words against known password hashes.
If it would take one second to put 100,000 dictionary words through a plain salt-and-hash process, then attackers who know your password hash could try 6 million different dictionary words and deriviatives every minute, or take more than one billion guesses every three hours.
On the other hand, if the salt-and-hash computations were stretched to take one second each, then the extra one-second delay when you tried to log in would cause little or no annoyance to you…
…but would reduce an attacker to just 3600 tries an hour, making it much less likely that they’d get enough time to guess anything but the most obvious passwords.
Several well-respected salt-hash-and-stretch algorithms are known, notably PBKDF2
, bcrypt
, scrypt
and Argon2
, all of which can be adjusted to increase the time needed to try individual password guesses in order to reduce the viability of so-called dictionary and brute force attacks.
A dictionary attack means you’re trying likely passwords only, such as every word you can think of from aardvark
to zymurgy
, and then giving up. A brute-force attack means trying every possible input, even weird and unpronouncable ones, from AAA..AAAA
to ZZZ..ZZZZ
(or from 0000..000000
to FFFF..FFFFFF
if you think in hexadecimal byte-by-byte terms).
What to do?
Slack says that about 1 in 200 of its users (0.5%, presumably based on records of how many shared invitation links were generated in the danger period), and that it will be forcing those users to reset their passwords.
Some further advice:
- If you’re a Slack user, you might as well reset your password even if you weren’t notified by the company to do so. When a company admits it has been careless with its password database by leaking hashes, especially over such a long period, you might as well assume that yours was affected, even if the company thinks it wasn’t. As soon as you change your password, you make the old hash useless to attackers.
- If you’re not using a password manager, consider getting one. A password manager helps to pick proper passwords, thus ensuring that your password ends up very, very far down the list of passwords that might get cracked in an incident like this. Attackers typically can’t do a true brute force attack, because there are just too many possible passwords to try out. So, they try the most likely passwords first, such as words or obvious word-and-number combinations, getting longer and more complex as the attack proceeds. A password manager can remember a random, 20-character password as easily as you can remember your cat’s name.
- Turn on 2FA if you can. 2FA, or two-factor authentication, means that you need not only your password to login, but also a one-time code that changes every time. These codes are typically sent to (or generated by) your mobile phone, and are valid only for a few minutes each. This means that even if cybercrooks do crack your password, it’s not enough on its own for them to take over your account.
- Choose a reputable salt-hash-and-stretch algorithm when handling passwords yourself.. In the unfortunate event that your password database gets breached, you will be able to give your customers precise details of the algorithm and the security settings you used. This will help well-informed users to judge for themselves how likely it is that their stolen hashes might have been cracked in the time available to attackers so far.