The LDAP ‘authentication’ anti-pattern
You could walk into just about any organization today, and you’re bound to find an LDAP directory populated with its users. Look a bit further, and you’ll likely find one or more applications using that directory for ‘authentication’. I say 'authentication' with quotes, because LDAP authentication is something of a misnomer. LDAP is a directory access protocol, designed for reading, writing, and searching a directory service. It's not an authentication protocol. LDAP authentication typically refers to the part of the protocol (binding) that is meant to establish who you are in order to determine what privileges you have to the information in the directory.
Over time, it’s become a de facto authentication service. The wide-spread availability of LDAP services, such as Active Directory, has turned it into an easy win for software developers who are looking to build authentication into their products. LDAP client libraries are available for just about any framework, and it’s relatively easy to get an LDAP integration functioning.
While using LDAP authentication might solve the development problem of how to authenticate users across an enterprise, it creates a host of other problems. There are inherent weakness and security issues that using LDAP introduces, that are not present in true authentication protocols.
In order to understand what these issues are, we first need to understand how LDAP authentication actually works.
How LDAP ‘authentication’ works
Consider the following situation (it’s rather absurd but bear with me).
Let’s say I order a parcel from an online store, only to have it delivered when I wasn’t home. The driver leaves a ‘sorry we missed you’ card in my mail box asking me to visit the local parcel pick-up point to collect the package in my own time. I arrive at the collection point, and the person behinds the counter asks for my name and address, and the keys to my house so they can validate who I am. They get in their car and drive to my house. They approach the front door, insert my key, and turn it. The door opens! They have a look inside for some evidence that I actually live there like some photos on the wall, or some mail with my name on it. They drive back to the parcel centre and let me know they have been able to successfully confirm my identity and I can have my package! Great!
Logistical issues aside, there are a quite a few problems with this situation. What if the attendant wasn’t trustworthy, and they took a copy of my key? What if they were trustworthy, but left the key lying around long enough for someone else to copy it? What if they were mugged, and my keys were stolen off them? Once the keys leave my possession, I really can’t be sure who has them and what they will be used for.
Thankfully in the real world, we have documentation like driver’s licenses and passports to prove our identities. I can hand over a piece of documentation that is issued to me by a 3rd party we both trust, such as a government agency, and my identity can be proven without giving away my keys.
In the LDAP world, we still have to hand over our keys to a 3rd party to unlock the door on our behalf. We give our password to the third party and they try to get into the LDAP server with it. If the password works, then you must be the owner of that password. However, now we have the same problem that we have when we hand over our keys. We really don’t know what is going to happen to those credentials and what they could be used for. If the credentials were compromised, the attacker would not just have access to unlock the LDAP door, but any application using those same credentials.
Thankfully, in the wider world of authentication, we have passports and drivers licenses too! Authentication protocols like Kerberos, SAML and OpenID Connect all issue tokens to 3rd parties that prove you are who you say you are, without having to hand them your keys. As LDAP was never designed to be an authentication protocol, it does not have appropriate mechanisms to do this.
LDAP’s weaknesses as an authentication system
Shumon Huque wrote a fantastic article in 2007 - LDAP Weaknesses as a Central Authentication System which he highlights 3 specific problems with the approach of authenticating using LDAP.
1. The application probably isn't secure enough to be touching credentials
Shumon makes the very valid point that it is far easier to defend a small set of authentication servers against an attack, than it is to defend a large population of application servers.
Authentication servers are generally locked down and run by people with significant expertise in security.
On the other hand, application servers have a very different security profile, and are more likely to be compromised. They have less rigorous protection, run more complex software stacks and are more likely to have security bugs. They are also more likely to be run by people who do not have an in-depth knowledge of security. That's not a criticism of the hard-working application administrators out there – getting security right is hard, getting it wrong is too easy!
The problem becomes that if a single application server is compromised, all the credentials that were used during the window of compromise are also compromised. Any other system that those users could log into with those same credentials, can also be considered compromised.
2. The LDAP server cannot enforce the security of the authentication mechanism used to obtain the credentials
The security of the transaction cannot be guaranteed by the LDAP server. While the LDAP server might for example be able enforce binding over TLS to ensure credentials are not transmitted in plain text, it never played a role in capturing those credentials in the first place. The application might be receiving the password over an insecure channel.
3. The user must reveal their authentication secret to a 3rd party
A user's password, or authentication secret, should remain that, a secret. It should be known only to the authentication system, and the user themselves. When using LDAP for authentication, the user must disclose their secret to a 3rd party, for them to replay that secret against the LDAP directory.
It's probably important to call out here, that with true authentication protocols such as Kerberos, and even the older NTLM, the user secret never passes over the network. The client device and server use cryptographic operations to prove they both have the same secret, without ever exchanging the secret itself.
I'm going to add a few of my own concerns to Shumon's points. These relate to my personal experience, primarily with consumers of Active Directory;
4. Many developers don't know how LDAP works well enough to use it correctly
One of my previous blog posts details how anonymous and unauthenticated binds have tricked many developers into letting unauthorized users into their applications. Unauthenticated binds are one of the subtleties in the protocol that even the most seasoned LDAP professionals are unaware of.
Directories are complex, and they can store an enormous amount of organizational information and provide a highly customizable way of doing that. I've seen so many cases where the developer of an application assumed a specific object class or attribute existed, and the whole thing falls over when it doesn't. To authenticate a user, you shouldn't need to have a working knowledge of the structure of the data stored in a directory. An authentication protocol should abstract away the detail of the underlying object store.
5. Application administrators often don't configure LDAP clients correctly
One of the frustrating things about managing an Active Directory in a large distributed environment, is that it's difficult to determine when services are using AD as an LDAP directory, and how the application administrators have configured their LDAP client.
Some of the configuration horrors I’ve seen include;
- Hardcoding DNs in applications, or using DNs in bind configuration. I've seen countless incidents caused by a rename or move of an object within in the directory, because someone has hard coded a DN somewhere. (A side note to those performing simple binds against AD - you don't need to use a DN to do this. AD also provides alternative DN formats that are more robust than using a traditional DN).
- Using personal user accounts as a ‘bind’ account instead of a service account (guess what happens when that person leaves the organization)
- Sending passwords in plain-text over port 389
- I’ve seen applications with a check box to optionally ‘validate certificate’ when connection to AD using TLS (port 636). Why is this even an option? You are going to throw a password at an endpoint, and you’re not even going to check if it’s the endpoint that you think it is?
It’s easy to get an LDAP client working, but just because it’s working, doesn’t mean the configuration is correct.
6. LDAP authentication and modern authentication are mutually exclusive
An application using LDAP for authentication will forever be limited to usernames and passwords. Trying to implement modern technologies such as multi-factor authentication and single sign on are virtually impossible (unless you are going to roll your own, which is a bad idea in its own right). The FIDO alliance aims to make passwords a thing of the past. Granted, this is a long term vision, but every application using LDAP authentication is going to stand in the way of an organization going password-less.
What are the alternatives?
Web applications today really have no need to use LDAP for authentication. There are many great web-enabled authentication protocols such as SAML, WS-Federation and OpenID Connect that do not require 3rd party applications having to touch credentials. Any number of products are available that provide these services, including Active Directory Federation Services (built into Windows Server), or hosted offerings such as Microsoft's Azure AD, Okta, Ping, and more. If you don’t have a federated identity provider available in your organization, you need to set one up as a first step.
When you are looking at new software, or going to tender, set a requirement that it must support modern authentication protocols. You may be able to use your organizations purchasing power to negotiate a better security outcome for your users. It’s ok if the vendor pushes back, or the business wants an application that only has LDAP support today. Have the conversation with the vendor anyway and tell them you want them to add support for modern authentication protocols to their product roadmap. It gets the conversation going. The more customers ask for it, the more likely they are to build it. However, if none of their customers ask for it, they’ll never do it.
A trend I’m really happy to see is a growing number of ‘thick-client’ desktop applications supporting modern authentication protocols. These apps have typically been an LDAP authentication stronghold. There are a growing number of SDKs such as the Microsoft Authentication Library (MSAL) that make it easy for developers to drop-in support for modern authentication into their mobile and desktop applications.
Ultimately, there is a reality to accept in that not all applications today support modern authentication protocols, and perhaps they never will. Implementing a total ban on LDAP authentication is likely not possible in any organization. However, LDAP authentication should be strongly discouraged within the organization. It should only be considered when no other options are available. When going to market for new software, mandate modern authentication support as a requirement. Have vendors or application owners prove that LDAP authentication is the only option before allowing it. Don't offer it as a commodity authentication service.
Comments
That's its biggest strength: once as admin has learned how to setup an app with LDAP once, it's pretty much that way forever after that because everything supports LDAP. Buying a server? It almost assuredly supports LDAP.
I think there ought to be an LDAP 2.0 that is as easy but addresses at least the most egregious points you made.