CVE-2026-9091
Executive Summary
CVE-2026-9091 is a critical logic flaw in Casdoor, an open-source identity and access management platform. The vulnerability resides in the social-login binding flow, specifically within the controllers/auth.go file. When a user authenticates via a social login provider (e.g., Google, GitHub) and binds that account to an existing Casdoor account, the HandleLoggedIn function is called directly without first invoking checkMfaEnable. This bypasses any configured Multi-Factor Authentication (MFA) requirements, allowing an attacker to gain authenticated access to a target account without providing a second factor.
The vulnerability affects all Casdoor versions up to and including 2.362.0. As of this report, no official patch has been released, and no public proof-of-concept (PoC) exploit code is available. The CVSS score is 9.1 (Critical) due to the ease of exploitation (no privileges required, no user interaction) and the high impact on confidentiality and integrity.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Casdoor is a Go-based application. The vulnerability is in the core source code, not in a third-party package. However, organizations using Casdoor as a dependency in their own Go projects should immediately review their usage of the social-login binding flow. The vulnerable code path is in controllers/auth.go, which is part of the Casdoor backend.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
- Base Score: 9.1 (Critical)
- Attack Vector (AV): Network – The vulnerability can be exploited remotely.
- Attack Complexity (AC): Low – No special conditions or race conditions are required.
- Privileges Required (PR): None – The attacker does not need any prior authentication.
- User Interaction (UI): None – The victim does not need to perform any action.
- Scope (S): Unchanged – The vulnerable component and the impacted component are the same.
- Confidentiality (C): High – An attacker can access all data associated with the victim account.
- Integrity (I): High – An attacker can modify account settings or perform actions as the victim.
- Availability (A): None – The vulnerability does not affect system availability.
Threat Level: Critical. The vulnerability allows complete bypass of MFA, which is a core security control. Given that Casdoor is often used as a central identity provider, a successful exploit could lead to lateral movement and privilege escalation within an organization.
Deep Dive & Mechanics
The vulnerability is a logic flaw in the social-login account binding flow. Casdoor allows users to link external social login accounts (e.g., Google, GitHub) to their existing Casdoor account. The intended flow is:
- User initiates social login.
- User is redirected to the social provider for authentication.
- Upon successful authentication, Casdoor checks if the social account is already linked to a Casdoor account.
- If not linked, the user is prompted to either create a new account or bind to an existing one.
- If binding to an existing account, the user must provide their Casdoor credentials and, if MFA is enabled, complete the MFA challenge.
- After successful binding, the user is logged in.
The flaw is in step 5. In controllers/auth.go, the HandleLoggedIn function is called directly after the binding is confirmed, without first calling checkMfaEnable. This means that even if MFA is enabled for the target account, the user is logged in without being prompted for the second factor.
The vulnerable code path is triggered when a user authenticates via a social provider and then binds that social account to an existing Casdoor account. The HandleLoggedIn function sets the session cookie and redirects the user to the dashboard, effectively granting full access.
Vulnerable vs. Patched Code
Vulnerable Code (Casdoor <= 2.362.0):
In controllers/auth.go, the binding flow likely looks similar to this (simplified):
func (c *ApiController) BindSocialAccount() {
// ... social login validation ...
// ... user authentication for binding ...
// Directly call HandleLoggedIn without MFA check
c.HandleLoggedIn(user)
}
Patched Code (Hypothetical):
The patched version would include a call to checkMfaEnable before HandleLoggedIn:
func (c *ApiController) BindSocialAccount() {
// ... social login validation ...
// ... user authentication for binding ...
// Check MFA before logging in
if c.checkMfaEnable(user) {
c.RequireMFA(user)
return
}
c.HandleLoggedIn(user)
}
The checkMfaEnable function would verify if MFA is enabled for the user and, if so, redirect them to the MFA verification page before granting access.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A Casdoor instance (version <= 2.362.0) with at least one user who has MFA enabled.
- A social login provider (e.g., Google, GitHub) configured in Casdoor.
- A social account that is NOT already linked to the target Casdoor account.
Exploitation Steps:
- Identify Target: Find a Casdoor instance and a user with MFA enabled. This can be done by attempting to log in and observing the MFA prompt.
- Initiate Social Login: Navigate to the Casdoor login page and click on the social login button (e.g., "Sign in with Google").
- Authenticate with Social Provider: Log in to your social account.
- Bind to Existing Account: Casdoor will prompt you to either create a new account or bind to an existing one. Choose "Bind to existing account."
- Provide Target Credentials: Enter the username and password of the target Casdoor account.
- Bypass MFA: The system will not prompt for MFA. You will be logged in directly as the target user.
Expected Outcome: Full access to the target user's account, including all applications and resources that rely on Casdoor for authentication.
Blue Team (Defensive)
Detection Steps:
- Monitor Social Login Events: Look for successful social login events that are immediately followed by account binding without an MFA challenge.
- Audit Logs: Check Casdoor audit logs for the
HandleLoggedInevent that occurs without a precedingMFAChallengeorMFAVerifiedevent. - User Behavior Analytics: Flag accounts that suddenly have a new social login provider linked, especially if the account has MFA enabled.
- Network Monitoring: Monitor for unusual traffic patterns to the Casdoor API endpoints related to social login and account binding.
Honeypot Strategy:
- Create a decoy Casdoor account with MFA enabled and a fake social login provider.
- Monitor for any attempts to bind a social account to this decoy account.
- Alert on any successful binding without MFA verification.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests to
/api/bind-social-accountor similar endpoints. - Successful login events without a preceding MFA challenge in the same session.
- Unusual social login provider usage (e.g., a user who normally uses Google suddenly using GitHub).
Host IOCs:
- Casdoor audit logs showing
HandleLoggedInwithoutMFAChallengefor the same user session. - New social login provider entries in the user's profile without a corresponding MFA event.
Log Patterns:
[INFO] User <username> logged in via social bindingwithout[INFO] MFA challenge completedin the same session.[WARN] MFA bypass detected for user <username>(if custom logging is implemented).
Detection Engineering
YARA Rule
rule CVE_2026_9091_Casdoor_MFA_Bypass {
meta:
description = "Detects Casdoor source code with MFA bypass in social login binding"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2026-9091"
severity = "critical"
strings:
$s1 = "HandleLoggedIn" ascii wide nocase
$s2 = "checkMfaEnable" ascii wide nocase
$s3 = "BindSocialAccount" ascii wide nocase
condition:
$s1 and $s3 and not $s2
}
Sigma Rule
title: Casdoor MFA Bypass via Social Login Binding
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects successful login events in Casdoor that bypass MFA during social login binding
author: Valters IT
date: 2025-04-10
tags:
- attack.t1190
- cve.2026.9091
logsource:
product: casdoor
service: audit
detection:
selection:
EventID: 'HandleLoggedIn'
filter:
EventID: 'MFAChallenge'
condition: selection and not filter
falsepositives:
- Legitimate MFA bypass if MFA is disabled for the user
level: critical
Suricata Rule
alert http any any -> any any (msg:"CVE-2026-9091 Casdoor MFA Bypass - Social Login Binding"; flow:to_server,established; content:"POST"; http_method; content:"/api/bind-social-account"; http_uri; content:"HandleLoggedIn"; http_server_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable Social Login: Temporarily disable the social login feature in Casdoor until a patch is available.
- Enforce MFA for All Users: Ensure that MFA is enabled for all users, but note that this does not mitigate the vulnerability.
- Monitor Logs: Actively monitor Casdoor audit logs for any suspicious social login binding events.
Long-Term Fix:
- Apply the official patch once released by the Casdoor maintainers.
- If patching is not possible, modify the source code to add a call to
checkMfaEnablebeforeHandleLoggedInin the binding flow.
Workaround:
- Implement a reverse proxy (e.g., Nginx) that inspects requests to
/api/bind-social-accountand blocks them if the user has MFA enabled. This is a fragile workaround and not recommended for production.
Valters IT Signature
This report was generated by Valters IT Cyber Threat Intelligence. For questions or further analysis, contact threatintel@valtersit.com.