Serious security problem in Digest Authentication
Current implementation of the Digest Authentication in lighttpd seems to be equivalent to an (insecure) basic authentication, that is, once an attacker obtains a valid request header he can access any file in a protected directory at any time.
Basically an attacker can simply "replay" an old request with the same credentials and he can use it for different objects by sending the same header (that contains valid "Authorization:") with the modified "GET".
How to reproduce:
Get (e.g sniff) the full http request header with the valid "Authorization:" and use it (e.g. cat header.txt | nc your.server.ip.addr 80) to get access to any file in a protected directory. Simple example attached. Tested with 1.4.19 and 1.4.20.
Some of the problems with the lighttpd digest authentication implementation have been pointed out before:
It seems that there are two problems:
1. the main problem is that mod_auth is not rejecting requests that contain "uri=" (in a "Authorization:" header) that does not match Request-URI (in a "GET "). Simple patch against 1.4.20 is attached (use patch -p1 and it will work with 1.4.19 too).
2. mod_auth doesn't store generated nonces (and possibly their generation time) and counters (nc) associated with them and thus it can't ensure that the counter increases for each of the nonce values that it has issued and it is not rejecting bad requests. When computing MD5 sums it relies only on the data provided in a request (plus password stored on the server) and this is causing to accept re-used headers.
RFC 2069, section 3.2, points out that a good implementation can protect against replay attacks but "a replay attack against digest authentication would usually be pointless for a simple GET request since an eavesdropper would already have seen the only document he could obtain with a replay. This is because the URI of the requested document is digested in the
client response and the server will only deliver that document". Unfortunately lighttpd delivers any document because of the problem 1.
- configure lighttpd to use digest authentication, add user 'bob' and add auth.require for directory /test
- open a browser, make a request to the server and provide valid bob's password while sniffing the http headers
- save the full http request header that contains "GET /test/" with a valid "Authorization:" to a separate file and send the header again to the server (e.g cat header.txt | nc your_server_ip 80)
- put some test files into the /test directory then manually modify the header.txt by changing GET to something like GET /test/testfile1.txt to get any file which is in /test
Updated by gstrauss about 5 years ago
- Status changed from New to Patch Pending
Pending patches reject URI mismatch and expire nonce after 10 mins, sending WWW-Authenticate: ... stale=true to client so that it will recreate a new digest using the included (new) nonce. These changes make lighttpd mod_auth Digest a better choice than Basic auth starting with lighttpd 1.4.41 (which has not yet been released at the time this is being written)
Excerpt from https://www.rfc-editor.org/rfc/rfc7616.txt Section 5.13:
The bottom line is that any compliant implementation will be
relatively weak by cryptographic standards, but any compliant
implementation will be far superior to Basic Authentication.
Also available in: Atom