Digest auth nonces are not validated
A malicious client attempting Digest authentication with lighttpd can arbitrarily invent nonces so long as the timestamp is in a reasonable range for lighttpd. That is, the second part of the nonce is not validated at all. The relevant RFCs recommend that the nonce is constructed as a cryptographic hash of a secret and a timestamp. Then a received nonce can be validated by recomputing the hash and comparing it to the received hash. Alternatively, it recommends keeping a database of issued nonces and rejecting any that were not issued. The latter is often infeasible due to the associated performance cost.
Verifying nonces still does not prevent replay attacks. It is just one step towards hardening the method.
use constant time comparison when comparing digests
(mitigation for brute-force timing attacks against digests
generated using the same nonce)
- Tracker changed from Bug to Feature
The relevant RFCs recommend that the nonce is constructed as a cryptographic hash of a secret and a timestamp. Then a received nonce can be validated by recomputing the hash and comparing it to the received hash. Alternatively, it recommends keeping a database of issued nonces and rejecting any that were not issued. The latter is often infeasible due to the associated performance cost.
https://www.rfc-editor.org/rfc/rfc7616.txt discusses various approaches and tradeoffs, including security level, mitigations for replay attacks, CPU overhead, database/storage, added latency (round-trips) for user requests, and more. In multiple places, RFC7616 suggests that servers should strongly prefer providing HTTP Digest Authentication via a secure channel, e.g. over TLS.
lighttpd provides a compliant implementation of RFC7616, though improvements can of course be made. lighttpd's current implementation does not require persistent data (e.g. across server restarts) and does not require any shared state or shared secrets between multiple lighttpd worker processes or between multiple servers in a server farm.
5.12. Parameter Randomness The security of this protocol is critically dependent on the randomness of the randomly chosen parameters, such as client and server nonces. These should be generated by a strong random or properly seeded pseudorandom source (see [RFC4086]).
lighttpd uses a pseudorandom source to generate nonces and limits the lifetime. The changing nonces make things more difficult for an attacker sniffing traffic to obtain the password from the hashed data, which is the raison d'être of Digest Authentication.
It is true that the current lighttpd implementation does not validate nonces and so an attacker could provide both nonce, cnonce, and nc. However, I did not find any reference in RFC7616 where validating digest auth nonces is required. Please provide a link. Until then, I consider this a feature request for enhancements, and not a bug.
I will consider adding some configuration options (feature enhancements) to allow for some additional hardening techniques to be applied, but some of these hardening techniques might not work well with some setups (e.g. server farms which load balance without request stickiness, or even multiple lighttpd worker processes), so they must be optional.
Please note: the strength of the nonce is an entirely separate challenge from protection against replay attacks. Please share in more detail why you feel that validating the nonce significantly hardens the implementation and why time should be spent here before implementing additional options to mitigate replay attacks.
To wit, a man-in-the-middle will intercept client traffic, can downgrade client to use MD5, and use pre-generated rainbow tables to determine password, absent any interaction with the server. For a brute-force password attack against a server, an attacker can request a nonce from the server and reuse it, as lighttpd does not validate number of nonce uses. I could go on, but hope that this demonstrates that an attacker's ability to provide the nonce is not a terrible thing when there is an absense of attack monitoring (validating nonce reuse, nonce count (nc), ...)
All that said, it is important to remember the benefit of having any RFC7616-compliant implementation of Digest Authentication:
5.13. Summary By modern cryptographic standards, Digest Authentication is weak. But, for a large range of purposes, it is valuable as a replacement for Basic Authentication. It remedies some, but not all, weaknesses of Basic Authentication. Its strength may vary depending on the implementation. In particular, the structure of the nonce (which is dependent on the server implementation) may affect the ease of mounting a replay attack. A range of server options is appropriate since, for example, some implementations may be willing to accept the server overhead of one-time nonces or digests to eliminate the possibility of replay. Others may be satisfied with a nonce like the one recommended above, i.e., restricted to a single IP address and a single ETag or with a limited lifetime. 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.
I mostly agree with what you say. I derived the recommendation from the example given in the RFC. This is not the formal "recommends" language indeed.
Other software projects (e.g. Apache) considered comparable issues CVE-worthy and not feature requests. (e.g. CVE-2018-1312)
I'm less sure about the implications of the problem.
I have updated the docs for mod_auth to be more explicit with the recommendations of RFC 7617 which strongly recommends using a secure channel, e.g. TLS.
Regarding CVE, just about any bug can be a CVE, and a CVE is just about required for certain distros (e.g. Debian) to backport patches.
I'm less sure about the implications of the problem.
lighttpd 1.4.54 added support for algorithm=SHA-256. The version of lighttpd in Debian Buster (lighttpd 1.4.53) only supports the deprecated algorithm=MD5, which is well-known to be insecure. Using Digest auth over an unencrypted channel (with any webserver) without disabling MD5 is insecure due to the possibility of downgrade attacks. However, MD5 is enabled by default to maintain compatibility with existing clients which do not support anything other than Digest algorithm=MD5
As I said above: improvements can of course be made in lighttpd's implementation of Digest auth, and I'll keep this ticket open to do so.
Also available in: Atom