Live data from Hacker News

Okta Bcrypt incident lessons for designing better APIs

n0rdy.foo

71–80 of 169 posts

Re: Okta Bcrypt incident lessons for designing better APIs

#71
post #3

Bcrypt is a password hash, not a KDF, which is the way it was used in this API. It's super unclear to me why they wanted a string-based KDF here at all; does anyone have more context? I've in the past been annoying about saying I think we should just call all password hashes "KDFs", but here's a really good illustration of why I was definitely wrong about that. A KDF is a generally-useful bit of cryptography joinery;…

So let me take on the burden of stupid here: how are a password hash and a string-based KDF different? (I mean, the oldest well-known example of the former literally calls itself a PBKDF.) I understand this particular function from strings to large fixed numbers was limited in the length of the string it would accept, and I agree that’s a problem, but it feels like a problem orthogonal to the distinction you’re drawi…

There is a huge amount of overlap, in that most modern password hashes can be used and are sort of fundamentally based on the idea of a string KDF. The big differences are, as you can see here, that a string or password KDF will take an arbitrarily long string, and that a KDF produces some specific raw random output, and a password hash produces a verifier string (the raw random hash, plus usually some metadata encoded some way; for bcrypt, that's the algorithm and cost and salt, for instance).

Re: Okta Bcrypt incident lessons for designing better APIs

#72
post #13

That is such a rookie mistake. It's not some hidden information that bcrypt has a 72 char limit. Pretty widely documented in multiple implementations and languages. How does a company whose only job is security screw that up so badly?

> It's not some hidden information that bcrypt has a 72 char limit. Pretty widely documented in multiple implementations and languages.

One of the points of the article is that documentation isn’t enough: one cannot allow callers to misuse one’s API.

Re: Okta Bcrypt incident lessons for designing better APIs

#73
post #28

Earlier quoted context omitted.

Yeah, I think both of the following would have worked if they wanted the password involved in a cache key and they wanted bcrypt to be used: * bcrypt(SHA-512(PW || stuff)) * SHA(stuff || bcrypt(PW)) Disclaimer: Not cryptography advice. It's still unclear to me why the password is in there.

For 'unlimited' input size it should be SHA-3-512. Maybe too slow, but Bcrypt is slower, right? Less things to go wrong too.

All of the SHA functions allow unlimited input size. And yes, bcrypt computation time dwarfs that of SHA-3.

The SHA-3 family has "extendable-output functions," which can ostensibly be used to generate unlimited numbers of bits (albeit with only a given security level). These are new to SHA-3.

Re: Okta Bcrypt incident lessons for designing better APIs

#74
post #28

Earlier quoted context omitted.

For 'unlimited' input size it should be SHA-3-512. Maybe too slow, but Bcrypt is slower, right? Less things to go wrong too.

All of the SHA functions allow unlimited input size. And yes, bcrypt computation time dwarfs that of SHA-3. The SHA-3 family has "extendable-output functions," which can ostensibly be used to generate unlimited numbers of bits (albeit with only a given security level). These are new to SHA-3.

SHA-3 has more internal state, it really is plausibly better at handling very large data. If 'unlimited' is really less than a gigabyte, there's no problem. It's mostly the preimage series of attacks and length extension at that point. SHA-3 is better on those. SHA-512 has zero length extension attack resistance.

Re: Okta Bcrypt incident lessons for designing better APIs

#75

Reminds me of when I saw a junior developer calling SHA-1 on an incrementing integer ID, with no salt. We had a long talk about it, he thought it was too "scrambled" to allow anyone to recognize what was being done. He shouldn't have been so junior, he was 4 or 5 years into his career. I had to be the bad guy and override his decision without further discussing why it was a bad idea, and I really tried for a good 45…

I've seen this before, a belief that just because the output looks random that it is secure. It's like storing license plates -- just hashing them without additional seasoning is of little use, because the number of possible license plates is so low that they can easily be brute forced. Similarly, a developer I worked with once claimed that CRC32 was sufficient verification because CRC32s changed so drastically depen…

I guess it feels good to let someone know that what they're doing is not cryptographically secure, but at the same time, you have to tell them that seemingly random numbers and/or letters doesn't mean they've come up with something useful.

I've tried to stay positive and explain that they will fool nearly everyone, the technology they used is usually recognizable to the type of people that would want to bypass it for their own gain (or knowledge, assuming white hat types poking around). Usually putting a spin on how they came up with something that looks secure was a great idea, but the type of people that will exploit something like what they built, will recognize patterns easily (and now that AI is around, you could even make them feel better by stating how there is software built to recognize these patterns).

Re: Okta Bcrypt incident lessons for designing better APIs

#76
post #74

Earlier quoted context omitted.

All of the SHA functions allow unlimited input size. And yes, bcrypt computation time dwarfs that of SHA-3. The SHA-3 family has "extendable-output functions," which can ostensibly be used to generate unlimited numbers of bits (albeit with only a given security level). These are new to SHA-3.

SHA-3 has more internal state, it really is plausibly better at handling very large data. If 'unlimited' is really less than a gigabyte, there's no problem. It's mostly the preimage series of attacks and length extension at that point. SHA-3 is better on those. SHA-512 has zero length extension attack resistance.

Internal state length may be a bit of a red herring (note that SHA-3 makes up for that longer internal state by ingesting more data per round), but SHA-3 probably has a higher security margin than the SHA-2 construction mostly because we have had sponge constructions for less time than we have had Merkle-Damgard constructions. NIST basically forced a higher security margin on SHA-3. You are correct about the length extension attacks (although these are mitigated by using SHA-2-512/256 for example), but I don't think that matters here.

Re: Okta Bcrypt incident lessons for designing better APIs

#77

Earlier quoted context omitted.

They didn't want a KDF, as far as I know, but they wanted a hash function with unlimited input size. Including the username in the hash input gives you guaranteed domain separation between users that you don't get from salts/nonces. Its a generally good idea if you have a hash function with unlimited input size (all modern cryptographic hash functions except bcrypt have unlimited input size).

> but they wanted a hash function with unlimited input size I'm kind of baffled how they came to use bcrypt for this. Bcrypt is not exactly subtle about only supporting 72 bytes of input. And this is at a company who provides auth as a service; I've got to imagine they had multiple engineers who knew this (I guess not working on that code). Hell, I know this and I've only used bcrypt twice and I'm nowhere near a secu…

BCrypt should loudly fail if more than 72 bytes are sent to its input.

Re: Okta Bcrypt incident lessons for designing better APIs

#78
post #55
post #45

Earlier quoted context omitted.

I feel like the "authentication company should have known" thing is unuseful; most developers at "security" companies are just ordinary generalist developers. Ironically, I think they boned themselves by trying to be too clever here, not too casual.

You don't think a company whose entire reason for being is providing security services for other companies should have designs related to authentication reviewed by security experts?

I was an employee of a company providing security services. I can attest to that company being filled with generalist programmers.

None were trained in security principles. None were security experts. And there was no security review.

Re: Okta Bcrypt incident lessons for designing better APIs

#80
This is a completely unreasonable API. It reminds me of the `mysql_real_escape_string` vs. `mysql_escape_string`. The default API must be the strict one. You should be able to configure it to be broken but silent truncation is an insane piece of functionality. There is no universe in which this is logical. One might as well just have everything return void* and then put in the documentation what type to cast to. The invariant is clearly a historical accident.

As a mistake, it's fine. Everyone writes up things like that. But defending it as an affirmatively good decision is wild.

Post reply on HN