oss-sec mailing list archives

Re: CVE Request: mini-httpd (<= v1.30) is affected by a response discrepancy information exposure (CWE-204)


From: Solar Designer <solar () openwall com>
Date: Thu, 13 Dec 2018 11:20:50 +0100

Hi,

Thank you for this additional detail.

On Thu, Dec 13, 2018 at 08:46:56AM +0100, Salva Peir?? wrote:
The htpasswd password for the "user" is generated by htpasswd from
apache2-utils:amd64 (= 2.4.25-3+deb9u6) on Debian

# Generate password "user" for "user"
$ /usr/bin/htpasswd -c auth/.htpasswd user
New password: <user>
Re-type new password: <user>
Adding password for user user

$ cat  auth/.htpasswd
user:$apr1$5.vGoLoA$OrxfML2lNUHvhMJrIC7lP.

Then a request is made to mini-httpd:

$ curl http://user@127.0.0.1:8000/auth/

This causes the mini-httpd to invoke crypt(3) with the following arguments
cryptpass = crypt(key, salt), I've added printf's to mini_httpd.c to report
the actual
arguments being passed and the value returned by crypt():

$ mini_httpd -D -p 8000 -h 127.0.0.1 -l /dev/stderr
key "" salt $apr1$Eh4Xgu3L$YIbNfgDcC1bRGBQWKMS.A1 cryptpass (null)
errno 22 strerror Invalid argument

This tells us that mini_httpd isn't compatible with Apache httpd's
htpasswd.  mini_httpd uses system-provided crypt(3), whereas Apache
httpd's htpasswd by default generates its own password hashes that are
generally not supported by system-provided crypt(3).

Then mini_httpd.c receives a SIGSEGV when performing strcmp() on the NULL
cryptpass at mini_httpd.c:2407. The cause of the NULL return value is that
the salt given to crypt() is invalid as show by errno=EINVAL.  So crypt(3)
is setting
errno=EINVAL to report that the htpasswd file generated by apache2-utils is
not
valid for being used with mini_httpd.

Exactly.  That's an interoperability issue and a robustness bug.  But to
call it a vulnerability is a stretch, in my opinion.

It doesn't allow for the attack you had described ("remotely enumerate
valid htpasswd usernames").  It only allows to detect existence of
usernames that are listed with unsupported hash types (or with otherwise
incorrect hash encoding strings), which is server-side misconfiguration.

Plenty of other projects had to add checks that crypt(3) return value is
non-NULL, and would crash on a NULL return before.  We didn't treat most
of these as vulnerabilities, and didn't assign CVE IDs.

Two notable exceptions are Cyrus SASL CVE-2013-4122 and PostgreSQL
CVE-2014-0066.  I couldn't easily find any reasoning why they got CVE
IDs, but these cases might in fact be special: the password hash
encoding string might be provided by the remote system.  If so, this
opens up other issues as well, where maliciously high cost settings
encoded in there would allow for remote DoS, which is worse than the
local DoS possible via .htpasswd files.  But that's a separate topic,
being discussed e.g. in:

Consider introducing limits on resource usage by maybe-rogue hash encodings
https://github.com/besser82/libxcrypt/issues/54

There was a tiny bit of discussion of the Cyrus SASL issue here:

https://www.openwall.com/lists/oss-security/2013/07/15/1

in which Sebastian Krahmer suggested that the missing NULL return check
could potentially allow for an authentication bypass if a thread could
consume so much heap address space that a valid allocation at the NULL
address would exist.  I think that while an issue like this might exist
on some system, the possibility of such allocation succeeding should be
treated as the vulnerability.  Otherwise we'd have to treat every NULL
dereference bug anywhere as a vulnerability, which isn't practical and
distracts attention from making such allocations impossible.

To summarize:

I think your finding needs a fix, and the fix you propose is correct and
sufficient, but it isn't a vulnerability and doesn't need a CVE ID.

Thanks again,

Alexander


Current thread: