Microsoft Exchange 5.0’s credential cache security problems

The other day, I wrote about the Exchange 5.0 NNTP (and POP3, and Exchange 5.5 IMAP) server’s credential cache.

Well, the credentials cache was my first experience with a customer reported security vulnerability.  As reported in Windows IT Pro magazine, the password cache resulted in a “vulnerability” being reported to Microsoft.

The problem occurs when a user logs on to the Exchange 5.0 POP3 server with a username and password.  Then that user logs onto the domain and changes their domain password.

Unfortunately, because of the credentials cache, the user could still use their old password!  Why was this?  Well, when they logged onto their account, we cached their token, and their credentials (the username, domain, mailbox name, user password, and some extra salt, like their IP address).  On their next logon, if the credentials were still in the cache, we’d get a hit on the credentials, and we’d re-use the token.  Now, their NEW password also worked, in that case, we wouldn’t find the credentials in the cache, and we’d call LogonUser and create a new token for the user. 

But the security researcher in this case still complained because they were still able to use the OLD password, even though it was no longer on the domain.  And they’d be able to continue using the password, until it aged out of the cache.

I still have the opinion that this behavior wasn’t a security vulnerability.  The credentials cache would only allow a password to be cached for a maximum of 2 hours, and if a user account was inactive for more than 15 minutes, the credentials would also be discarded.  So the longest potential period of the old credentials being considered valid was 2 hours after the user changed their password.  On the other hand, most POP3 clients polled the server every 10 minutes, this meant that if a user logged into their POP3 client and left it logged in, we’d never have to delay their “check new mail” for a domain authentication – which could take up to 15 or more seconds in pathological circumstances (if one of the domain controllers went down and we needed to re-discover a domain controller for the domain, for example).  So at the cost of having a users token in memory for 2 hours, we were able to significantly improve their experience using the Exchange POP3 server.

We also provided registry configuration parameters to allow the user to tune any and all of these behaviors, the Windows IT Pro article indicates how to turn it off.

For Exchange 2000, the NNTP, POP3 and IMAP server were moved out of the Exchange store, and the credentials cache went away, and was replaced with a different implementation, unfortunately I don’t know how that worked.

For the person who asked how we implemented the credentials cache, it was relatively simple – we took the users clear text username, domain and password (and the salt as mentioned above, which included their IP address), calculated the MD5 hash of the credentials and used that as the key to a hash table.  This relied on the fact that the various clients sent the users credentials in plain text.  If they used NTLM or other more secure authentication protocols, then we simply used the built-in NT authentication mechanisms to log the user on.



Comments (5)

  1. Anonymous says:

    Why couldn’t the creditential cache be purged for that specific entry in case of a change? BTW this very issue is addressed in the Kerberos article Larry when talking about "disabling ticket reusage" 😛 Anyhow awesome stories you have. Keep up the good work.


  2. Anonymous says:

    Faced with a similar issue with caching successful logons I set up the cache so that if anyone logged on using a password other than the one that had been used to create the cache entry, we’d burn the cache entry. This meant that if you typed the wrong password, you’d have to re-authenticate, but it also meant that while the security guards were escorting you from the building, the sysadmin could kill your cache entry without dumping the whole cache.

    Hmm… I guess that’s what Tibor just said too!!! 🙂

  3. Anonymous says:

    It’s a vulnerability if the user changed their password because they knew it had been compromised – you’ve given the hostile a 2 hour window where they can continue to use the password, in spite of the user taking the correct action. That’s bad, which is probably why someone decided to fix it.

  4. Anonymous says:

    Here’s the problem with purging the cache – it requires that I have the ability to FIND the entry in the cache. And that requires that I keep the users password in clear text. Which I wasn’t willing to do (because of the obvious security vulnerability).

    Changing credentials in the case of a change requires that I KNOW about the change. And as a client of the LogonUser API, I have no way of determining if/when the user has changed their password last. I suspect I might have been able to call NetUserGetInfo() to find it, but that would take as long as the LogonUser call. Which would defeat the entire purpose of the cache.

    Michael, you’re right. And that IS a threat. But it’s mitigated in this case – the user just has turn off their email client for 15 minutes, and the bad credentials would age out of the cache. That’s exactly why there are two timeouts – a 15 minute inactivity timeout and a 2 hour active timeout.

  5. Anonymous says:

    Don’t forget that even with their old password, you’d need to have their IP (and maybe computer name and who knows what else larry put in there) to be able to get back to that cache entry. It could be changed, sure, but it’d damage your network connectivity if it’s still in use (or simply not work if it’s on another subnet) and probably be ineffective.

Skip to main content