CVE-2025-46815
Executive Summary
CVE-2025-46815 is a critical vulnerability in ZITADEL, an identity infrastructure platform. The flaw resides in the Session API's handling of IdP (Identity Provider) intents. An attacker with network access to the application's callback URI can repeatedly reuse a successful IdP intent's id and token values to authenticate as a different user. This effectively bypasses the intended one-time-use mechanism for these intents, leading to session hijacking and unauthorized access. The CVSS score of 8.0 reflects the high impact on confidentiality and integrity, with no user interaction required. The vulnerability is patched in versions 2.70.10, 2.71.9, and 3.0.0. No public exploit code or proof-of-concept is available at this time.
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
ZITADEL is a Go-based application. The vulnerability is in the core server logic, not in a third-party package. However, organizations using ZITADEL as a dependency in their own Go projects should ensure they are not embedding a vulnerable version. The fix is a server-side patch; no package manager (NPM, PyPI, RubyGems) is involved.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The attacker can exploit this remotely.
- Attack Complexity (AC): Low (L) – No special conditions are required.
- Privileges Required (PR): None (N) – No authentication needed to initiate the attack.
- User Interaction (UI): None (N) – The victim does not need to perform any action.
- Scope (S): Unchanged (U) – The exploit does not affect other components.
- Confidentiality (C): High (H) – Full user session data is exposed.
- Integrity (I): High (H) – Attacker can perform actions as the victim.
- Availability (A): High (H) – The attacker can disrupt the victim's session.
Threat Level: Critical. The combination of network access, no privileges, and no user interaction makes this highly exploitable. The EPSS score of 0.0% suggests no active exploitation in the wild yet, but the risk is significant.
Deep Dive & Mechanics
The ZITADEL Session API allows developers to initiate authentication flows via external IdPs (e.g., Google, GitHub). This is done through "idp intents." When a user successfully authenticates via an IdP, the client receives an id and token on a predefined callback URI. These values are then used to complete the session creation.
The vulnerability arises because the id and token are not invalidated after a single use. An attacker who can observe or intercept the callback URI (e.g., by having network access to the application's endpoint) can capture these values. They can then repeatedly send the same id and token to the Session API to authenticate as the original user, effectively hijacking the session.
Key Points:
- The attack does not require the victim to be actively using the application after the initial intent.
- The attacker only needs access to the callback URI, which is often a predictable endpoint.
- Multi-factor authentication (MFA) prevents full API access but does not prevent the initial session hijack.
Vulnerable vs. Patched Code
The fix involves ensuring that each IdP intent's id and token are single-use. The patched code likely adds a check to invalidate the intent after it has been consumed.
Vulnerable Code (Conceptual):
func handleIdpIntent(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
token := r.URL.Query().Get("token")
// No check if this intent was already used
session, err := authenticateWithIdp(id, token)
if err != nil {
// handle error
}
// create session
}
Patched Code (Conceptual):
func handleIdpIntent(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
token := r.URL.Query().Get("token")
// Check if intent was already consumed
if isIntentConsumed(id) {
http.Error(w, "Intent already used", http.StatusForbidden)
return
}
session, err := authenticateWithIdp(id, token)
if err != nil {
// handle error
}
// Mark intent as consumed
markIntentConsumed(id)
// create session
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Access to the ZITADEL application's callback URI (e.g.,
https://target.com/auth/callback). - A valid IdP intent
idandtoken(can be obtained by observing a legitimate user's authentication flow).
Steps:
- Intercept the callback URI after a user authenticates via an IdP. Extract the
idandtokenparameters. - Send a POST request to the Session API endpoint (e.g.,
/session/authenticate) with the capturedidandtoken. - The server will create a new session for the victim user.
- Use the session cookie to access the application as the victim.
Example cURL:
curl -X POST https://target.com/session/authenticate \
-H "Content-Type: application/json" \
-d '{"id": "captured_id", "token": "captured_token"}'
Blue Team (Detection & Defense)
Detection:
- Monitor for multiple authentication requests using the same
idandtokenvalues. - Alert on rapid succession of session creation from the same IP or user agent.
- Log all IdP intent usage and flag any intent that is used more than once.
Defense:
- Apply the patch immediately (upgrade to 2.70.10, 2.71.9, or 3.0.0).
- Implement network segmentation to limit access to the callback URI.
- Enable MFA for all users to mitigate the impact of session hijacking.
- Use Web Application Firewall (WAF) rules to block repeated requests with the same
idandtoken.
Indicators of Compromise (IOCs)
- Network: Repeated POST requests to
/session/authenticatewith identicalidandtokenparameters. - Logs: Multiple successful session creations for the same user from different IP addresses or user agents.
- Application: Unusual session activity, such as a user performing actions they normally wouldn't.
Detection Engineering
YARA Rule
rule CVE_2025_46815_ZITADEL_Session_Hijack {
meta:
description = "Detects exploitation attempts of CVE-2025-46815 via repeated IdP intent usage"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-46815"
strings:
$s1 = "/session/authenticate" ascii wide nocase
$s2 = "id=" ascii wide nocase
$s3 = "token=" ascii wide nocase
condition:
all of ($s*) and #s1 > 1
}
Sigma Rule
title: CVE-2025-46815 - ZITADEL Session Hijack via IdP Intent Reuse
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects multiple authentication requests using the same IdP intent id and token
author: Valters IT
date: 2025-04-10
logsource:
category: application
product: zitadel
detection:
selection:
event: "session.authenticate"
id: "same_id"
token: "same_token"
condition: selection | count() > 1
falsepositives:
- Legitimate retries due to network issues (unlikely)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-46815 - ZITADEL Session Hijack Attempt"; flow:to_server; content:"POST"; http_method; content:"/session/authenticate"; http_uri; content:"id="; http_uri; content:"token="; http_uri; threshold:type both, track by_src, count 2, seconds 60; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade ZITADEL to version 2.70.10, 2.71.9, or 3.0.0.
- If upgrade is not possible, restrict network access to the callback URI to trusted IPs only.
Long-term:
- Implement rate limiting on the Session API endpoint.
- Enforce MFA for all users.
- Conduct a security audit of all IdP integration points.
- Monitor for any unusual session activity.
Workarounds:
- No official workarounds are available. Upgrading is the only recommended action.
Valters IT