Community
Participate
Working Groups
Build Identifier: 20100917-0705 See RFC 2617 chapters 3.2.2 and 3.2.3 A correct implementation of the digest authentication should verify that the nonce-count specified by the client not only is part of the signature, but is also incremented (at minimum for every nonce sent by the server). Without this, the server is open for Man-in-the-middle and replay attacks where by someone snoops the authentication response from the client and replays this to gain access to the server. If an old or replayed count is seen, then the server should send a 401 to the client with a new nonce. It is also advised that the nonce be expanded to include details of the context path Reproducible: Always Steps to Reproduce: 1. Configure jetty up for digest authentication 2. Use a client (browser or library) to provide a valid response, which is authenticated by jetty 3. Sniff the response (off the net, through a proxy, or for the test case use something simple like Fiddler) 4. Happily replay the response against the server from any location to gain access.
How should the server remember the nonce count? It can't put it in the session, as an attacker could just leave out the session ID. It can't associate it with the connection, as multiple clients might get multiplexed onto a connection by an intermediary. How is this typically done?
One option would be to add a unique client id encoded in the nonce sent to the client (similar to what's done with the timestamp at the moment to check for maxage). Make an LRU map of the client ids and the latest nonce count, and return 401 with new nonce if it's not there or not greater than previous count.
This has been resolved by have a non zero max age on nonces and keeping a concurrent queue of recently created nonces plus a map of noce to count to check the nc value is increasing. fix will be in 7.5.2
Ok, sounds good. I take it by lru map of nonces you maintain a nonce generated per client?
Checked out the latest source, there seems to be a bug in that there's no comma before the "stale" parameter returned in response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"" + _loginService.getName() + "\", domain=\"" + domain + "\", nonce=\"" + newNonce((Request)request) + "\", algorithm=MD5, qop=\"auth\"" + " stale=" + stale);
Fixed, thanks for catching that!