I will explain the scenario, and then explain the issue, since it was kind of an “Ah Ha” moment when I came across this.
- ADAM is provisioned with a userProxy object, which redirects simple binds back to the Active Directory user object that contains the SID. Anonymous directory enumeration is disabled on the ADAM instance.
- 3rd party LDAP app is configured to use ADAM instance for a simplified BIND, since it cannot handle multiple naming contexts to bind against. Some Applications cannot use GC instances for authentication (or are not supported doing so) It is still surprising that many “enterprise” applications from BIG names still do not support binding to more than one naming context, or referral chasing.
A simplified view of how the application authentication works:
- Application presents a logon box to user, where they type in their name/password credentials
- Application uses a service account to bind to the ADAM directory, to search if the user exists, and to return that user’s DN.
- If account is found, the application re-binds (simple) using that DN, and password the user entered in
- The ADAM server proxies that authentication request back to the Active Directory that contains the SID for that userProxy object
- ADAM will return a SUCCESS or NOSUCCESS code back to the application
- Application reads status code and either allows a user entry or denies it based upon the status code
It turns out that users have discovered they can logon to the 3rd party app by entering a user name, and a BLANK password. The 3rd party application lets them in as that user, and thinks everything is hunky dory.
I received the call out of fear from the application owner, that Active Directory was allowing their users to be any other user in their application if they did not put in a password when authenticating. I was quite puzzled by this, since I knew that AD disallowed a blank password to be set, so I feared it maybe a bug with how ADAM was configured somewhere. Furthermore, Users who discovered this, found themselves having their AD accounts being locked out.
So I contacted a friend at MS to ask if he had seen this issue before, and asked him to inquire around if anyone had. I quickly received the answer to my problem.
Due to RFC 2829 – Authentication Methods for LDAP, which states:
- 5. Anonymous authentication Directory operations which modify entries or access protected attributes or entries generally require client authentication. Clients which do not intend to perform any of these operations typically use anonymous authentication. LDAP implementations MUST support anonymous authentication, as defined in section
- 5.1. LDAP implementations MAY support anonymous authentication with TLS, as defined in section 5.2. While there MAY be access control restrictions to prevent access to directory entries, an LDAP server SHOULD allow an anonymously-bound client to retrieve the supportedSASLMechanisms attribute of the root DSE. An LDAP server MAY use other information about the client provided by the lower layers or external means to grant or deny access even to anonymously authenticated clients. 5.1. Anonymous authentication procedure An LDAP client which has not successfully completed a bind operation on a connection is anonymously authenticated. An LDAP client MAY also specify anonymous authentication in a bind request by using a zero-length OCTET STRING with the simple authentication choice.
So by reading that, if a simple bind is made with a blank password, LDAP will treat it as an attempt to bind as anonymous to the ADAM instance. Since ADAM conforms to the LDAP RFC, it MUST allow anonymous, which in the above example, would return a SUCCESS status if tried by an application.
Since the application is not reading data from the directory, the option to disallow anonymous enumeration would have no effect in stopping this. The application is simply looking if the user/password presented returns a success scenario.
The fun part is, that ADAM is passing the blank password back to AD, which counts this as a bad password attempt and increments the bad password count. If the Domain policy limit is reached, the AD account becomes locked out.
The “easy” solution for this, was to require the Application to not allow a blank/null password to be submitted from their authentication prompt. I would like to say it’s “easy”, but unfortunately some applications that come my way are developed by people not so keen on security, so there may be no way to modify the already purchased app.
So this leaves my group stuck holding the bag, which leads me down the path of thinking about requesting a DCR to Microsoft to set a bit, to disallow anonymous bind if a blank password is presented.
This would break RFC compliancy for ADAM, but I think this could be up to the Admin to determine if it’s a risk they can live with, if they can’t control the applications that will be authenticating to the ADAM instance.
Any thoughts out there?
I forgot to mention, I had thought to myself “Did I somehow enable anonymous binds and forget?”, since part of the design was to not-allow anonymous. I did check the config entry as outlined in the ADAM FAQ:
ADAM does not accept anonymous bind requests by default. To enable anonymous LDAP operations in ADAM, you must set the seventh character of the dsHeuristics value to 2.
This indeed was set to NOT allow anonymous binds, which based on the wording I would assume mean that anonymous binds would be rejected. In actuality, an anonymous bind is a SUCCESS, but you can’t enumerate the directory structure from that point on. Perhaps the wording should be changed to reflect this?
[Update 2]: RFC has been updated to 4513 for “Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms”