In LdapInterop/UserSynchronizer.php, synchronizeLdapUser() detects when an LDAP login matches an existing native (non-LDAP) Matomo user and logs a warning, but then falls through instead of aborting:
} else {
if (!$userMapper->isUserLdapUser($existingUser['login'])) {
$logger->warning("Unable to synchronize LDAP user '{user}', non-LDAP user with same name exists.", ...);
} else {
$userUpdater->updateUserWithoutCurrentPassword(...);
}
}
$userMapper->markUserAsLdapUser($user['login']);
return $userModel->getUser($user['login']);
Because the warning branch does not return or throw, markUserAsLdapUser() runs unconditionally and the method returns the existing native user record. In default LdapAuth mode this means a directory entry whose uid equals an existing native account is authenticated as that native account, and the native account is silently converted to an LDAP user (its stored password hash is overwritten on a subsequent login).
Suggested fix: in the non-LDAP collision branch, abort synchronization (throw, or return a failure the caller treats as an auth failure) instead of falling through, and only call markUserAsLdapUser() after a successful synchronization.
Tested on LoginLdap 5.2.1 with Matomo 5.13. Filed as a regular hardening bug per a maintainer suggestion.
In
LdapInterop/UserSynchronizer.php,synchronizeLdapUser()detects when an LDAP login matches an existing native (non-LDAP) Matomo user and logs a warning, but then falls through instead of aborting:Because the warning branch does not return or throw,
markUserAsLdapUser()runs unconditionally and the method returns the existing native user record. In defaultLdapAuthmode this means a directory entry whoseuidequals an existing native account is authenticated as that native account, and the native account is silently converted to an LDAP user (its stored password hash is overwritten on a subsequent login).Suggested fix: in the non-LDAP collision branch, abort synchronization (throw, or return a failure the caller treats as an auth failure) instead of falling through, and only call
markUserAsLdapUser()after a successful synchronization.Tested on LoginLdap 5.2.1 with Matomo 5.13. Filed as a regular hardening bug per a maintainer suggestion.