CVE-2026-9098
Executive Summary
CVE-2026-9098 is a critical authentication bypass vulnerability in Casdoor, an open-source identity and access management platform. The flaw resides in the SAML callback handler (controllers/auth.go), which fails to verify that a received SAMLResponse corresponds to a previously issued AuthnRequest. This allows an attacker controlling a registered upstream Identity Provider (IdP) to send unsolicited SAML responses or replay captured responses across different sessions. Additionally, if an administrator disables or deletes an IdP during an active SAML flow, the handler still processes the response using a stale provider snapshot. Successful exploitation grants persistent unauthorized access to the Casdoor application, effectively bypassing authentication for any user the attacker can impersonate.
Affected Ecosystem: Go (Casdoor is a Go-based application).
Supply Chain & Package Security: This vulnerability is not a direct supply chain compromise of a package registry (e.g., PyPI, NPM). However, Casdoor is often deployed as a central identity provider, meaning a compromise here can cascade to all downstream applications relying on Casdoor for authentication. Organizations using Casdoor as a SAML IdP or SP should treat this as a critical supply chain risk for their entire application ecosystem.
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
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – Exploitable remotely.
- Attack Complexity (AC): Low (L) – No special conditions required; attacker only needs control of a registered IdP.
- Privileges Required (PR): None (N) – No authentication needed to trigger the vulnerability.
- User Interaction (UI): None (N) – No victim action required.
- Scope (S): Unchanged (U) – The vulnerable component is the only affected system.
- Confidentiality (C): High (H) – Full access to all user data and sessions.
- Integrity (I): High (H) – Attacker can impersonate any user and perform actions on their behalf.
- Availability (A): High (H) – Attacker can disrupt legitimate access by hijacking sessions.
CVSS Score: 9.8 (Critical)
Threat Level: Critical – Immediate patching or mitigation required.
Deep Dive & Mechanics
The vulnerability is rooted in the SAML protocol implementation within Casdoor's controllers/auth.go. The SAML authentication flow typically works as follows:
- AuthnRequest: Casdoor (Service Provider) generates a unique AuthnRequest and sends it to the configured IdP.
- SAMLResponse: The IdP authenticates the user and returns a signed SAMLResponse containing the user's identity.
- Verification: The SP must verify that the SAMLResponse corresponds to a pending AuthnRequest (e.g., by checking the
InResponseToattribute) and that the response is not stale.
The Flaw: Casdoor's handler at /api/acs accepts any well-formed SAMLResponse without verifying the InResponseTo attribute. This means:
- Unsolicited Response Attack: An attacker controlling a registered IdP can craft a SAMLResponse for any user (e.g.,
admin@example.com) and send it directly to/api/acs. Casdoor will process it and create a session for that user. - Replay Attack: A legitimate SAMLResponse captured from a previous session can be replayed in a different browser session or after the original flow has expired. Since no nonce or timestamp validation is enforced, the response is accepted again.
- Stale Provider Snapshot: If an administrator disables or deletes the IdP after a SAML flow has started, the handler still uses the provider configuration loaded at the start of the request. This means even a decommissioned IdP can be used to authenticate users.
Attack Scenario:
- Attacker registers a malicious IdP in Casdoor (or compromises an existing one).
- Attacker crafts a SAMLResponse with
NameIDset toadmin(or any target user). - Attacker sends a POST request to
https://victim-casdoor.com/api/acswith the crafted SAMLResponse. - Casdoor processes the response, creates a session for
admin, and returns a session cookie. - Attacker uses the session cookie to access Casdoor as
admin.
Vulnerable vs. Patched Code
Vulnerable Code (Casdoor <= 2.362.0):
// controllers/auth.go (simplified)
func (c *ApiController) Callback() {
samlResponse := c.GetString("SAMLResponse")
// No verification of InResponseTo or AuthnRequest state
providerID := c.GetString("state") // state is not validated
provider := getProvider(providerID)
// Uses provider snapshot loaded at request start, even if provider is deleted
user, err := provider.ParseResponse(samlResponse)
if err == nil {
c.SetSession("user", user)
}
}
Patched Code (Hypothetical Fix):
// controllers/auth.go (patched)
func (c *ApiController) Callback() {
samlResponse := c.GetString("SAMLResponse")
state := c.GetString("state")
// Verify state corresponds to a pending AuthnRequest
if !validateAuthnRequestState(state) {
c.CustomAbort(403, "Invalid SAML request state")
return
}
providerID := extractProviderFromState(state)
provider := getProvider(providerID)
// Check if provider is still active
if provider == nil || provider.Status != "active" {
c.CustomAbort(403, "Provider is disabled or deleted")
return
}
// Verify InResponseTo matches the original AuthnRequest
if !verifyInResponseTo(samlResponse, state) {
c.CustomAbort(403, "SAMLResponse does not match any pending request")
return
}
user, err := provider.ParseResponse(samlResponse)
if err == nil {
c.SetSession("user", user)
}
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Access to a registered IdP in the target Casdoor instance (or ability to register one).
- Network access to the Casdoor
/api/acsendpoint.
Exploitation Steps:
- Craft a Malicious SAMLResponse:
- Use a tool like
samlifyorpython3-samlto generate a SAMLResponse. - Set
NameIDto the target user (e.g.,admin). - Sign the response with the IdP's private key (attacker-controlled).
- Use a tool like
- Send the Unsolicited Response:
curl -X POST https://victim-casdoor.com/api/acs \ -d "SAMLResponse=$(cat malicious_saml_response.xml)" \ -d "state=attacker_provider_id" - Capture Session Cookie:
- The response will include a
Set-Cookieheader with a session token. - Use this cookie to access Casdoor as the impersonated user.
- The response will include a
Replay Attack:
- Intercept a legitimate SAMLResponse (e.g., via MITM or log inspection).
- Replay it to
/api/acsin a different browser session.
Blue Team (Detection & Hardening)
Immediate Mitigation (No Patch Available):
- Disable SAML Authentication: If SAML is not critical, disable it in Casdoor configuration.
- Restrict IdP Registration: Only allow trusted administrators to register IdPs.
- Network Segmentation: Restrict access to
/api/acsto known IdP IP addresses. - Monitor for Unsolicited SAML Responses: Log all SAMLResponse processing and alert on responses without a corresponding AuthnRequest.
Long-Term Fix:
- Implement
InResponseTovalidation in the SAML handler. - Add nonce and timestamp checks to prevent replay attacks.
- Ensure provider status is checked after the response is received, not just at request start.
Indicators of Compromise (IOCs)
Network IOCs:
- POST requests to
/api/acswithSAMLResponseparameter but no correspondingAuthnRequestin logs. - Multiple identical SAMLResponses from different IP addresses (replay attack).
- SAMLResponses with
NameIDset to privileged users (e.g.,admin,root).
- POST requests to
Log IOCs:
- Casdoor audit logs showing successful authentication via SAML without a prior
AuthnRequest. - Session creation events for users who did not initiate a login flow.
- Casdoor audit logs showing successful authentication via SAML without a prior
File IOCs:
- Modified
controllers/auth.go(if attacker patches the code). - Suspicious IdP configurations in Casdoor database.
- Modified
Detection Engineering
YARA Rule
rule CVE_2026_9098_SAML_Unsolicited_Response {
meta:
description = "Detects unsolicited SAMLResponse in Casdoor logs"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2026-9098"
strings:
$saml_response = "SAMLResponse"
$no_authn = "AuthnRequest" nocase
$api_acs = "/api/acs"
condition:
$saml_response and $api_acs and not $no_authn
}
Sigma Rule
title: Casdoor Unsolicited SAML Response Detection
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects POST requests to /api/acs without a prior AuthnRequest
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: casdoor
detection:
selection:
cs-method: POST
cs-uri-stem: '/api/acs'
cs-uri-query|contains: 'SAMLResponse'
filter:
cs-uri-query|contains: 'AuthnRequest'
condition: selection and not filter
falsepositives:
- Legitimate SAML flows where AuthnRequest is not logged
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2026-9098 - Casdoor Unsolicited SAML Response"; flow:to_server; http.method; content:"POST"; http.uri; content:"/api/acs"; http.client_body; content:"SAMLResponse"; pcre:"/SAMLResponse/"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable SAML authentication if not required.
- Restrict network access to
/api/acsto trusted IdP IPs. - Enable detailed logging for all SAML endpoints.
Patch Application:
- Monitor Casdoor releases for a patch (CVE-2026-9098 is currently unpatched).
- Apply the hypothetical patch described in the "Vulnerable vs. Patched Code" section.
Configuration Hardening:
- Enforce IdP certificate validation.
- Set short session timeouts to limit the window of exploitation.
- Implement multi-factor authentication (MFA) as a secondary layer.
Monitoring:
- Deploy the YARA, Sigma, and Suricata rules provided.
- Alert on any SAML authentication without a corresponding AuthnRequest.
Valters IT – DevSecOps & Cyber Threat Intelligence