CVE-2026-90961: MISP LdapAuth and LinOTPAuth Authentication Bypass via Empty or Non-String Credentials
The LdapAuth and LinOTPAuth authentication plugins in MISP contain an authentication bypass vulnerability. Both LdapAuthenticate and LinOTPAuthenticate replace CakePHP's FormAuthenticate class but fail to replicate its checkFields() input validation guard. As a result, the email and password fields extracted from the login request are passed to downstream authentication logic without verifying that they are non-empty strings.
In the LDAP authenticator, an empty or null password is forwarded to ldapbind(). Per RFC 4513 section 5.1.2, a bind request with a valid DN and an empty password constitutes an unauthenticated bind, which many LDAP directory servers accept as successful. An attacker who knows any valid user email address in the directory can therefore authenticate as that user without possessing a password. Additionally, non-string values (null, false, arrays) are either coerced to empty strings by ldapbind(), raise TypeErrors, or are misinterpreted as find conditions in findUser(), all of which can lead to unintended authentication outcomes.
In the LinOTP authenticator, the same missing guard allows non-string credentials to be concatenated into the LinOTP verification request, and in the mixed-authentication branch an empty password is accepted against a stored hash of the empty string.
A secondary issue in the LDAP authenticator is that newly created user accounts (auto-provisioned on first LDAP login) were assigned an empty password. Because the save path skips validation, the empty string is hashed and stored. If the user later ceases to be found in LDAP and the mixed-authentication fallback is used, the stored hash of the empty string verifies against an empty password, again permitting unauthenticated access.
The vulnerability requires that the affected plugin (LdapAuth or LinOTPAuth) is enabled on the MISP instance and that the attacker knows at least one valid email address registered in the directory or MISP user store. No prior authentication is required. Successful exploitation grants the attacker the full privileges of the impersonated user, which may include administrative access to threat intelligence data.
Version affected: ≤2.5.45
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
In the LdapAuthenticate auth flow, validate that both the email and password fields extracted from the login request are non-empty strings before invoking any authentication logic (before passing password to ldap_bind() and before any mixed-auth fallback verification). Reject non-string/empty values with a logged error and return false.
MISP LdapAuth plugin password/email validation (type and emptiness guard) = enabled - Configuration
In the LinOTPAuthenticate auth flow, validate that both the email and password fields extracted from the login request are non-empty strings before invoking any authentication logic (including the mixed-authentication branch). Reject non-string/empty values with a logged error and return false.
MISP LinOTPAuth plugin password/email validation (type and emptiness guard) = enabled - Operational
After applying the code fix, ensure any auto-provisioned LDAP users no longer have an empty-string password hash; confirm that auto-provisioned user accounts are assigned a cryptographically random password (not '') so the mixed-authentication fallback cannot verify an empty password hash.
Event History
Frequently Asked Questions
Which deployments have a clear authentication-bypass condition?
MISP deployments using the LdapAuth plugin are exposed when their LDAP directory accepts an unauthenticated bind with a valid DN and an empty password. An attacker also needs to know a valid directory user email address.
What credential values should be considered unsafe while assessing exposure?
Empty or null passwords can reach ldap_bind() without validation. Other non-string values, including false and arrays, may be coerced, cause errors, or be interpreted unexpectedly during user lookup.