Just came across a very strange behavior of the DBMS_LDAP.simple_bind_s and APEX_LDAP.authenticate procedure which I used to do a basic LDAP authentication against our MS Active Directory server.
I used the following simple test code
DECLARE vSession DBMS_LDAP.session; vResult PLS_INTEGER; BEGIN DBMS_LDAP.use_exception := TRUE; vSession := DBMS_LDAP.init ( hostname => 'your-active-directory-server' , portnum => 389 ); vResult := DBMS_LDAP.simple_bind_s ( ld => vSession , dn => 'CN=Wolf Patrick,[...rest of the DN...],DC=sphinx,DC=co,DC=at' , passwd => 'x' ); DBMS_Output.put_line('User authenticated!'); vResult := DBMS_LDAP.unbind_s(vSession); END;
which raised the expected error
ORA-31202: DBMS_LDAP: LDAP client/server error: Invalid credentials. 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece
because of the wrong password. But as soon as I set NULL for the passwd parameter I got the “User authenticated!” message!!!
Couldn’t believe that, so I also tried the APEX_LDAP wrapper package. Shows the same behavior with the following code!
BEGIN IF APEX_LDAP.authenticate ( p_username => 'Wolf Patrick' , p_password => NULL , p_search_base => '[...rest of the DN...],DC=sphinx,DC=co,DC=at' , p_host => 'your-active-directory-server' , p_port => 389 ) THEN DBMS_Output.put_line('ok'); ELSE DBMS_Output.put_line('not ok'); END IF; END;
So I did a final test with the built-in LDAP authentication scheme of Oracle APEX. The good news is that it captures this case and you are not able to login. So it looks like they are doing an extra check for a NULL password there.
But what does that mean?!?
- I’m a total moron and did something completely wrong. In that case please let me know!
- Our MS Active Directory server is set up wrong to accept NULL passwords for LDAP connections.
- MS Active Directory is a total piece of crap to accept NULL passwords. (BTW, I don’t know if other LDAP servers like Oracle OID show the same behavior)
- All applications which are using APEX_LDAP.authenticate or DBMS_LDAP.simple_bind_s in a custom authentication scheme have a huge security flaw in them.
Can someone test the above code against his MS Active Directory or some other LDAP server and let me know?
BTW, in my opinion APEX_LDAP.authenticate should behave the same as the built-in LDAP authentication scheme and return FALSE.
Update as of 13-Jan-2008: John Scott pointed into the right direction. DBMS_LDAP.simple_bind_s has to accept a NULL password, because this function is also used to authenticate against a LDAP server if you want to do an anonymous search in the LDAP directory. I think it wasn’t the best decision by the authors of the RFC 4513 to reuse the password parameter to decide if it’s an anonymous bind or not. An extra parameter would have been much better an clearer. Anyway, we have to deal with that problem now.
If you directly use DBMS_LDAP.simple_bind_s for authentication in your code, don’t forget to do a password IS NOT NULL check. If you use APEX_LDAP.authenticate you have to do the same.
But I have good news! APEX_LDAP.authenticate will be fixed in Oracle APEX 3.1 to include this check. Thanks to the APEX team!