HN.zip

Alpine Linux Security advisory: OpenSSH-server password authentication bypass

214 points by pantalaimon - 7 comments
NewJazz [3 hidden]5 mins ago
musl’s crypt() returns the string * as an error indicator when the key is over 256 bytes long. * is also exactly what the stored field contains for every account with no password, so the “hash” matches and the login succeeds.

Does anyone know why musl does this? Are they the only C library that behaves this way?

For a C library that famously tries to adhere to POSIX as much as possible, this seems like a crazy choice. From POSIX standard:

Upon successful completion, crypt() shall return a pointer to the encoded string. The first two bytes of the returned value shall be those of the salt argument. Otherwise, it shall return a null pointer and set errno to indicate the error.

https://pubs.opengroup.org/onlinepubs/9699919799/functions/c...

hnfong [3 hidden]5 mins ago
There's a very detailed trace of how the bug was developed over decades at sshhole.com and the relevant discussion in https://news.ycombinator.com/item?id=50378228
NewJazz [3 hidden]5 mins ago
Thanks yeah just woke up, finished making my way through the single-article website and still unclear if other libcs do the same thing (the article says libxcrypt picked it up, but only after musl did it).
worksonmine [3 hidden]5 mins ago
Apparently because some devs didn't check for NULL which resulted in crashes. Weird choice to fix other peoples' bad programming by deviating from the spec.
cyphar [3 hidden]5 mins ago
To be fair (as the sshole site mentions) it is also necessary to fake a password hash check to avoid timing side channels revealing to remote clients whether users exist, so returning a sentinel value is not a horrifically unreasonable solution to make sure even naive code does approximately the right thing.

Though I am surprised that all of the code examples do not use constant-time strcmp(). Actually, I wonder if even constant-time strncmp() would still leak information about whether the account is disabled because in that case both arguments are much shorter? Food for thought.

But yeah, the crypt(3) API is very 80s C, the man page even features a lengthy description of a long-deprecated and utterly broken hashing algorithm using DES that is even implied to be broken in the text itself (and the warning message is so old it refers to "parallel computers" as though they were a new concept). Given that the default mode is to use a broken hashing algorithm, I'm shocked anyone actually uses the libc crypt(3) -- surely it's trivial to just write your own that isn't awful...?

api [3 hidden]5 mins ago
TBH that sounds like a straight up bug in that it deviates dangerously from the spec.
throwa356262 [3 hidden]5 mins ago
Discussion from a few hours ago:

https://news.ycombinator.com/item?id=50377221