LDAP Authentication in PHP - Authenticated without giving a password

14,738

Solution 1

After doing some research, I reached a conclusion that the LDAP server we are using allows anonymous binds.

More info here: https://issues.jfrog.org/jira/browse/RTFACT-3378

WARNING: An attempt to bind with a blank password always succeeds because the LDAP protocol considers this to be an "anonymous" bind, even though a username is specified. Always check for a blank password before binding.

In order to go around this, I now check the password input field in PHP:

if (strlen(trim($user_pass)) == 0) {
    //login failed
} else {
    $ldaprdn = "DOMAIN\\" . $_POST["username"];
    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $_POST["password"]);
}

An empty password input (or whitespaces) will always return a login fail.

Solution 2

Using the 'simple' BIND authentication method, there are four possibilities:

  • null DN, null password (anonymous): no authentication takes place, therefore this session and authorization state are not safe
  • DN, null password (unauthenticated): no authentication takes place, therefore this session and authorization state are not safe
  • DN and password: authentication takes place and either succeeds or fails
  • null DN, password: no authentication takes place, therefore this session and authorization state are not safe

The 3d is the only one in which authentication takes place. Properly configured LDAP directory servers will reject the other 3 possibilities because, contrary to what the question states, authentication does not take place. A method of an API not throwing an exception or returning true does not indicate whether authentication took place. The BIND result contains an integer result code which indicates that authentication was successful or not.

see also

Solution 3

Before you nag the IT people, check if the value passed in the line

$ldapbind = ldap_bind($ldapconn, $ldaprdn, $_POST["password"]);

Is correct, you have probably checked this already, but do a

var_dump($ldaprdn); var_dump($_POST["password"]);

and see if the data is accurate.

Manually put the data like

$ldapbind = ldap_bind($ldapconn, "username", "password");

Also check if you have to give the entire DN, such as CN=Username,DC=xxx,DC=com for the username.

Also sometimes you have to give the name such as "User Name", rather than "user.name" because this is how it might be stored.

If all this fails, you can go eat the head of the IT people :-P

Share:
14,738
Jorg Ancrath
Author by

Jorg Ancrath

Updated on June 11, 2022

Comments

  • Jorg Ancrath
    Jorg Ancrath almost 2 years

    I'm getting a strange behavior on my LDAP Authentication, I need this to authenticate users with their AD credentials, this is what I have:

    session_start(); 
    $adServer = "MY IP"; 
    $ldapconn = ldap_connect($adServer) or $this->msg = "Could not connect to LDAP server.";
    
    $ldaprdn = "DOMAIN\\" . $_POST["username"];
    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $_POST["password"]);
    
    if ($ldapbind) {
    //$msg = "Successfully Authenticated";
        $_SESSION['loggedin'] = 1;
        $_SESSION['username'] = $username;
        header("Location: ../main.php");
    } else {
        header("Location: ../index.php?login_failed=1");
    }
    

    This is the different behaviors I get:

    • No username / No Password = authenticated (BAD)
    • Username / No Password = authenticated (BAD)
    • Incorrect Username/Password (both fields were given) = not authenticated
    • Correct Username/Password (both fields were given) = authenticated

    I find this hard to muster, all users are being validated if the password field is not being used. But if I do use the password field it only authenticates users with the correct credentials..

    Am I doing something wrong here or should I start nagging the IT people?