<< The Bcrypt algorithm was used to generate the cache key where we hash a combined string of userId + username + password. During specific conditions, this could allow users to authenticate by only providing the username with the stored cache key of a previous successful authentication. >>
So if the userid is 18 digits, the username is 52 characters, and the delimiters are 1 character each, then the total length of the non-secret prefix is 72, and bcrypt will drop the secret suffix.
You aren’t supposed to put more than the salt and the password into trad unix password hashes.
* They concatenated userId + username + password for a cache key
* Used BCrypt (which has a 72-byte limit)
* The concatenation could exceed 72 bytes, causing the password portion to be truncated
Why this is problematic:
* BCrypt is designed for password hashing, not cache key generation
* Mixing identifiers (userId, username) with secrets (password) in the same hash
* Truncation risk due to BCrypt's limits
Password storage should be separate from cache key generation. Use a random salt + appropriate hash function and for cache keys - use HMAC or KDF w/appropriate inputs
That should also mean that ca 50-52 character usernames are likely easily bruteforcable. Which makes the preconditions wider than those stated in the publication.
Potentially ignorant question, why would they go for bcrypt over say HKDF[1], especially since they mix in public data like the username and potentially userid?
This is obviously a huge mistake by Okta (for the love of God understand how your crypto functions work before you apply them) but at the same time, a crypto function with a maximum input length that also auto-truncates the data sounds like bad API design. You are basically asking for someone to goof up and make a mistake. It's much better to implement these things defensively so that the caller doesn't inadvertently make a mistake. Especially with a hashing algorithm, because there is no way to verify that the result is correct.
Agree with the spirit of the argument, but I disagree about the bad design. BCrypt has its trade-offs, you are expected to know how to use it when using it, specially if by choice.
It's like complaining about how dangerous an axe is because it's super sharp. You don't complain, you just don't grab the blade section, you grab it by the handle. And
I think it's more of a logic problem. I suspect the engineers made a false assumption that bcrypt can hash a trivial amount of data like some other hashing algos.
Also, are there any repercussions for this kind of stuff? I don't know, fines from the organizations they get compliance certifications from or something.
They had literally 1 job: secure authentication. This isn't the first time Okta has had a gaffe on a level that should cause any customer to reconsider. What's that saying, "Fool me once, shame on thee, fool me twice, shame on me". Don't get fooled by Okta a second, third, or fourth time.
[+] [-] fanf2|1 year ago|reply
https://man.openbsd.org/crypt
<< The maximum password length is 72. >>
So if the userid is 18 digits, the username is 52 characters, and the delimiters are 1 character each, then the total length of the non-secret prefix is 72, and bcrypt will drop the secret suffix.
You aren’t supposed to put more than the salt and the password into trad unix password hashes.
[+] [-] gzer0|1 year ago|reply
Core issue (okta's approach):
Why this is problematic: Password storage should be separate from cache key generation. Use a random salt + appropriate hash function and for cache keys - use HMAC or KDF w/appropriate inputs[+] [-] 3np|1 year ago|reply
[+] [-] magicalhippo|1 year ago|reply
[1]: https://datatracker.ietf.org/doc/html/rfc5869
[+] [-] a-dub|1 year ago|reply
[+] [-] marginalia_nu|1 year ago|reply
To be fair, they're basically salting with the userid and username. Still unorthodox to be sure.
[+] [-] 0x457|1 year ago|reply
[+] [-] jadengis|1 year ago|reply
[+] [-] sebastialonso|1 year ago|reply
It's like complaining about how dangerous an axe is because it's super sharp. You don't complain, you just don't grab the blade section, you grab it by the handle. And
[+] [-] mplewis|1 year ago|reply
[+] [-] djbusby|1 year ago|reply
Can't tell if it's issue with BCrypt or with the state-data going into the key, or combo-cache lookup tho.
[+] [-] ptcrash|1 year ago|reply
[+] [-] Forbo|1 year ago|reply
Go fuck yourselves.
Sincerely, Everyone in the industry
[+] [-] pluc|1 year ago|reply
[1] https://trust.okta.com/
[+] [-] cyberax|1 year ago|reply
-- With Love, Okta.
[+] [-] chanux|1 year ago|reply
[+] [-] hoffs|1 year ago|reply
[+] [-] err4nt|1 year ago|reply
[+] [-] _hyn3|1 year ago|reply
IMO, better to choose point solutions and combine them.
[+] [-] unknown|1 year ago|reply
[deleted]
[+] [-] demarq|1 year ago|reply
It’s was a fuzzer of some sort
[+] [-] Animats|1 year ago|reply
[+] [-] tedunangst|1 year ago|reply
[+] [-] lanstin|1 year ago|reply
[+] [-] lelanthran|1 year ago|reply
What's your point? That rewriting `bcrypt` in something else magically fixes this?
AIUI, the issue is that `bcrypt` only uses the first 72 bytes of the input to create a hash.