Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exchange Web Services server-to-server authentication without plaintext password?

I'm building a server application that runs automated processes that needs to be compatible with Exchange servers back to version 2007. I currently use OAuth through Azure AD for Office 365 connection, but I'm still trying to find a solution for on-premises Exchange pre-2013.

I've been reading about Exchange authentication (basic, NTLM, etc) and I can't seem to find any references to a long-term token system that will allow me to setup authentication with a one-time use password. I'd very strongly rather not store user passwords in a central DB, encrypted or not, as its a huge security responsibility and could be reverse engineered.

Is there something I'm missing?

Is there a way to authenticate to Exchange without a password each time?

like image 787
Rican7 Avatar asked Jul 20 '15 18:07

Rican7


People also ask

What is replacing EWS?

Microsoft Graph offers improvements over EWS in terms of security, simplicity, and efficiency. Switch to Microsoft Graph to take advantage of these improvements, all through one single endpoint.

Does Exchange Web Services support modern authentication?

Modern Auth (OAuth authentication) for EWS is only available in Exchange Online as part of Office 365. EWS applications using OAuth requires the "Full access to users' mailbox" permission to work. Full Mailbox Access is, therefore, the only permission type that can be granted for EWS Applications.

Is Exchange Web Services Basic Authentication?

Basic authentication is no longer supported for EWS to connect to Exchange Online. Use OAuth authentication in all your new or existing EWS applications to connect to Exchange Online. OAuth authentication for EWS is only available in Exchange Online as part of Microsoft 365.

How do I Authenticate an EWS application by OAuth?

To use OAuth with your application you will need to: Register your application with Azure Active Directory. Add code to get an authentication token to get an authentication token from a token server. Add an authentication token to EWS requests that you send.


1 Answers

Answering my own question as a follow-up, as I wasn't satisfied with some of the responses and/or what I was able to find through extensive searching.

After a lot of research looking into Exchange servers, how they authenticate, and the protocols supported and used, I found what I consider to be a best option: NTLM.

Now, let me explain.

The goal that I was trying to achieve was the following:

  • Be able to authenticate to an Exchange 2007+ server
  • Have the authentication be a "one-time-setup" through an initial process
  • Never store plain-text passwords (particularly in a platform/service central datastore)

With those points in mind:

  • I couldn't use "Basic" auth as it would require storing the user's password in plain-text in a central datastore
  • OAuth doesn't work as it's only supported on Exchange 2013+

With that, I was really only left with NTLM. Unfortunately I've known NTLM to have a rough history with security flaws over it's many-year legacy, but I dove into it more to see if it was somehow able to meet my requirements.

Unfortunately, NTLM has for a long time been kept a bit of a "secret" in terms of it's specification. It's a proprietary spec, so information regarding it's internals is unfortunately rather uncommon. For a long time, the only real source of specification information regarding NTLM was actually info that was reverse-engineered (thanks Eric Glass!). Thankfully, though, Microsoft did finally start to publish documentation on NTLM on their MSDN site more recently.

After looking into the protocol pretty heavily, and after running some tests on a test Exchange server in many different permutations of configurations, I realized that NTLM would actually fit all of my requirements. How? Well, thanks to the way that the protocol works, once a credential has been hashed (in one of the 3 ways that is possible in the spec [LM, NTv1, NTv2]) it doesn't need to be hashed again for the same target. This means that, similar to hashing a user's password for a typical registration mechanism, you can simply ask for the Exchange/NTLM credentials up-front and then hash the credentials one time.


NOTE!!! There is a catch!

Keep in mind that being able to hash the credential once and use it multiple times means that the hash is somewhat of a "password equivalent". What I mean by that, is that the hash can be used like a password once it's known, since it's one of the only pieces of information needed to authenticate in the future. (This is known colloquially as "pass-the-hash").

Considering the alternative, however, of storing a password in plain-text, this is still much better. Why? Because at least you're not storing a raw credential that could be used in any other authentication scheme or leaking a password that may be shared in other environments (yes, people unfortunately do actually do that).

Given that knowledge, great care should still be taken when storing these hashed credentials. Finally, if another stronger authentication scheme is able to be used, use it.


So, thanks to the way that the NTLM protocol works, it meets the requirements:

  • Be able to authenticate to an Exchange 2007+ server
    • NTLM is available in all Exchange servers 2007+
  • Have the authentication be a "one-time-setup" through an initial process
    • The credentials and target need only be entered once, as once an initial handshake is made with the server you'll know that the auth scheme works. (This of course doesn't consider that a remote Exchange server's configuration could be changed at any time. So proper error handling should still very much be put in place)
  • Never store plain-text passwords (particularly in a platform/service central datastore)
    • The hashed credential is stored instead. However great care should be taken, with a potentially dual-encryption technique employed, due to the "catch" explained in the earlier note.

Anyway, I hope someone else finds this at some point so that they don't have to do quite as much specification reading and experimentation as I had to.

Also, for what it's worth, as I noticed that open-source implementations of NTLM are not only rare but also more commonly only half-complete, my team has open-sourced our NTLM implementation in PHP. It's available on GitHub.

like image 108
Rican7 Avatar answered Oct 31 '22 00:10

Rican7