Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 336443

Summary: Security issue - HTTP DigestAuthenticator does not verify nonce count is incremented
Product: [RT] Jetty Reporter: art <zarbear>
Component: serverAssignee: Greg Wilkins <gregw>
Status: CLOSED FIXED QA Contact:
Severity: major    
Priority: P3 CC: jesse.mcconnell, jetty-inbox
Version: unspecified   
Target Milestone: 7.2.x   
Hardware: All   
OS: All   
Whiteboard:

Description art CLA 2011-02-06 03:58:02 EST
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.
Comment 1 Greg Wilkins CLA 2011-02-22 22:44:29 EST
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?
Comment 2 art CLA 2011-02-23 00:36:18 EST
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.
Comment 3 Greg Wilkins CLA 2011-09-20 03:03:25 EDT
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
Comment 4 art CLA 2011-09-24 07:51:20 EDT
Ok, sounds good.  
I take it by lru map of nonces you maintain a nonce generated per client?
Comment 5 art CLA 2011-09-29 09:42:51 EDT
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);
Comment 6 Jesse McConnell CLA 2011-09-29 17:57:48 EDT
Fixed, thanks for catching that!