In January last year, I wrote a (long) post detailing a curious behavior I stumbled across in Active Directory's LDAP interface. By providing a username, but leaving the password blank, you were authenticated as an 'anonymous user'. This is technically a valid LDAP behavior, and is known as an 'unauthenticated bind'. However it's obscure, not well known, and the cause of many security vulnerabilities.
To recap, the LDAP RFC states the following;
5.1.2. Unauthenticated Authentication Mechanism of Simple Bind
An LDAP client may use the unauthenticated authentication mechanism of the simple Bind method to establish an anonymous authorization state by sending a Bind request with a name value (a distinguished name in LDAP string form [RFC4514] of non-zero length) and specifying the simple authentication choice containing a password value of zero length
The RFC goes on to acknowledge this is an objectively terrible idea, and recommends that servers reject unauthenticated bind requests by default.
Unauthenticated Bind operations can have significant security issues (see Section 6.3.1). In particular, users intending to perform Name/Password Authentication may inadvertently provide an empty password and thus cause poorly implemented clients to request Unauthenticated access.
Additionally, Servers SHOULD by default fail Unauthenticated Bind requests with a resultCode of unwillingToPerform.
Sadly, Microsoft's Active Directory and Lightweight Directory Services products did not support disabling this behavior at all, let alone having it off by default as suggested by the RFC.
The good news is that in Windows Server 2019, Microsoft have added in the ability to disable unauthenticated binds. So Windows now joins all other major LDAP vendors in providing the capability to turn off this 'feature'
They stopped short of making it off by default, which would have been preferable, but at least it is an option now.
So, how do you enable it?
Using ADSIEdit, open the Configuration partition, and open the properties of the CN=Directory Service, CN=Windows NT, CN=Services, CN=Configuration object. Modify the msDS-Other-Settings attribute, and add a new entry for DenyUnauthenticatedBind=1
The setting takes effect immediately, and does not require a reboot.
Now, when you attempt to login without a password, it will fail with an Unwilling To Perform error message.
----------- res = ldap_simple_bind_s(ld, 'let me in', <unavailable>); // v.3 Error <53>: ldap_simple_bind_s() failed: Unwilling To Perform Server error: 00002035: LdapErr: DSID-0C0903AD, comment: The server has been configured to deny unauthenticated simple binds., data 0, v4563 Error 0x2035 The server is unwilling to process the request. -----------
That's all there is to it. You follow the the same process to apply the fix to your LDS instances.
Granted, it's not a perfect outcome - you still need to upgrade all your domain controllers and/or LDS servers to Windows Server 2019 to take advantage of this capability, but if this is Important to you, there is at least a solution available.
Time to start planning those upgrades...