Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-90961

CVE-2026-90961: MISP Auth Bypass Vulnerability

CVE-2026-90961 is an authentication bypass flaw in MISP LdapAuth and LinOTPAuth plugins that allows attackers to authenticate without valid passwords. This post covers technical details, affected versions, and mitigation strategies.

Published:

CVE-2026-90961 Overview

CVE-2026-90961 is an authentication bypass vulnerability in the LdapAuth and LinOTPAuth plugins for the Malware Information Sharing Platform (MISP). Both plugins replace CakePHP's FormAuthenticate class but omit the _checkFields() guard that validates credentials as non-empty strings. An unauthenticated attacker who knows any valid user email address can bind to the directory with an empty password, exploiting the RFC 4513 unauthenticated bind behavior. Successful exploitation grants full privileges of the impersonated account, including administrative access to threat intelligence data. Versions ≤2.5.45 are affected.

Critical Impact

Remote, unauthenticated attackers can log in as any known MISP user, including administrators, when LdapAuth or LinOTPAuth is enabled.

Affected Products

  • MISP versions ≤2.5.45 with the LdapAuth plugin enabled
  • MISP versions ≤2.5.45 with the LinOTPAuth plugin enabled
  • MISP deployments using auto-provisioned LDAP accounts that later fall back to mixed authentication

Discovery Timeline

  • 2026-09-14 - CVE-2026-90961 published to NVD
  • 2026-09-16 - Last updated in NVD database

Technical Details for CVE-2026-90961

Vulnerability Analysis

The vulnerability originates in two custom authentication components: LdapAuthenticate and LinOTPAuthenticate. Both classes replace CakePHP's FormAuthenticate rather than extending it. They read email and password from the login request and pass them directly to downstream authentication logic without validating type or non-emptiness.

In the LDAP authenticator, an empty or null password reaches ldap_bind(). RFC 4513 section 5.1.2 defines a bind with a valid Distinguished Name (DN) and empty password as an unauthenticated bind. Many directory servers respond with success. An attacker who knows any valid directory email address authenticates as that user without a password.

The LinOTP authenticator suffers the same missing guard. Non-string credentials are concatenated into the LinOTP verification request, and the mixed-authentication branch accepts an empty password against a stored hash of the empty string. A secondary flaw compounds the issue: auto-provisioned users receive an empty password that bypasses validation on save, producing a stored hash of the empty string that later verifies against empty input.

Root Cause

The root cause is improper input validation [CWE-20]. Both plugins skip the _checkFields() guard from FormAuthenticate, allowing empty strings, null, false, and arrays to flow into ldap_bind(), _findUser(), and LinOTP request construction.

Attack Vector

Exploitation requires network access to the MISP login endpoint and knowledge of one valid email address. The attacker submits a login request containing a valid email and an empty or non-string password. The LDAP bind succeeds as an unauthenticated bind, and MISP grants a session with the impersonated user's privileges.

php
        $userFields = $request->data['User'];
-        $email = $userFields['email'];
-        $password = $userFields['password'];
+        $email = isset($userFields['email']) ? $userFields['email'] : '';
+        $password = isset($userFields['password']) ? $userFields['password'] : '';
+
+        // This class replaces FormAuthenticate rather than extending it, so it has to
+        // repeat that class' _checkFields() guard: both credentials must be non-empty
+        // strings.
+        //
+        // RFC 4513 section 5.1.2: a bind request carrying a valid DN and an empty
+        // password is an unauthenticated bind, and many directories answer it with
+        // success. An empty password reaching ldap_bind() below would therefore
+        // authenticate anyone who knows a user's email address.
+        if (!is_string($email) || $email === '' || !is_string($password) || $password === '') {
+            CakeLog::error("[LdapAuth] Rejected login attempt with a missing or invalid email or password.");
+            return false;
+        }

Source: MISP security patch commit 0ee058548

Detection Methods for CVE-2026-90961

Indicators of Compromise

  • Successful MISP login events with no corresponding LDAP bind password in directory server logs.
  • Directory server audit logs showing bind operations with empty userPassword values.
  • MISP audit_logs entries showing session creation for administrative accounts from unfamiliar source IPs.
  • Unexpected data exports or API tokens generated by accounts that rarely log in interactively.

Detection Strategies

  • Correlate MISP application login events with LDAP directory bind logs to identify sessions produced by unauthenticated binds.
  • Search MISP logs for the patched error string [LdapAuth] Rejected login attempt or [LinOTPAuth] Rejected login attempt after applying the fix to identify probing attempts.
  • Alert on directory server responses to bind requests where the password field length is zero.

Monitoring Recommendations

  • Enable verbose logging on LDAP directory servers to capture bind DN and password presence for every attempt.
  • Forward MISP application logs and directory logs to a central analytics platform for correlation.
  • Monitor authentication anomalies such as new source geographies, unusual user-agents, or off-hours administrator logins.

How to Mitigate CVE-2026-90961

Immediate Actions Required

  • Upgrade MISP to the version containing commit 0ee058548 or later immediately.
  • Audit MISP users table for accounts with empty or default password hashes and reset them.
  • Rotate API keys and session tokens for any accounts that may have been impersonated.
  • Review recent MISP audit logs for suspicious logins during the exposure window.

Patch Information

The fix is available in the MISP repository via commit 0ee058548, which adds is_string() and non-empty checks to both LdapAuthenticate.php and LinOTPAuthenticate.php before credentials reach ldap_bind() or LinOTP request construction. See the MISP GitHub commit for full patch details.

Workarounds

  • Disable the LdapAuth and LinOTPAuth plugins until the patch is applied and switch to FormAuthenticate with strong local passwords.
  • Configure the upstream LDAP directory to reject unauthenticated binds by setting disallow bind_anon in OpenLDAP or the equivalent directive in Active Directory.
  • Place MISP behind a reverse proxy that enforces client certificate authentication or IP allowlisting for the login endpoint.
bash
# OpenLDAP: reject unauthenticated binds in slapd.conf
disallow bind_anon
require authc

# Verify no MISP users have an empty-string password hash
mysql -e "SELECT id, email FROM misp.users WHERE password = SHA2('', 256) OR password = '';"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.