CVE-2024-47000
Executive Summary
CVE-2024-47000 is a critical authorization bypass vulnerability in Zitadel, an open-source identity management platform. The flaw resides in the user account deactivation mechanism, which fails to properly enforce deactivation for service accounts. A deactivated service account retains the ability to request tokens, allowing an attacker who has compromised or previously had access to a deactivated service account to continue authenticating and accessing protected resources. This effectively nullifies the deactivation security control for service accounts, leading to potential unauthorized access to applications, APIs, and sensitive data.
The vulnerability has a CVSS score of 8.1 (High) and affects multiple Zitadel versions prior to the patched releases. While no public proof-of-concept (PoC) or exploit code is currently available, the attack vector is straightforward: an attacker with knowledge of a deactivated service account's credentials can still obtain valid tokens. The EPSS score is 0.0%, indicating low exploitation likelihood at this time, but the impact is severe due to the potential for persistent unauthorized access.
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 distributed as a Go binary and Docker container. The vulnerability is in the core authentication logic, not in a specific package dependency. However, organizations using Zitadel as part of their identity infrastructure should treat this as a supply chain risk because a compromised service account can lead to lateral movement and data breaches across connected systems. Ensure that all Zitadel instances are updated to the patched versions and that service account credentials are rotated post-patch.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
- Base Score: 8.1 (High)
- Attack Vector: Network (AV:N) – The vulnerability can be exploited remotely.
- Attack Complexity: Low (AC:L) – No special conditions are required.
- Privileges Required: Low (PR:L) – An attacker needs valid credentials for a deactivated service account.
- User Interaction: None (UI:N) – No user action is needed.
- Scope: Unchanged (S:U) – The vulnerable component and the impacted component are the same.
- Confidentiality Impact: High (C:H) – Full read access to protected resources.
- Integrity Impact: High (I:H) – Full write/modify access to protected resources.
- Availability Impact: High (A:H) – Potential to disrupt services via token abuse.
Threat Level: High. The vulnerability allows an attacker to bypass a critical security control (account deactivation) and maintain persistent access. While no public exploit exists, the attack is trivial to execute once credentials are obtained.
Deep Dive & Mechanics
Zitadel uses a token-based authentication system where service accounts (machine-to-machine accounts) are issued JWT tokens upon successful authentication. The deactivation mechanism is intended to revoke the account's ability to authenticate, but due to a logic flaw, the token issuance endpoint does not check the deactivated status for service accounts.
Root Cause: The authorization check for service account deactivation is missing or incorrectly implemented in the token generation flow. When a service account is deactivated, the system should reject any token requests for that account. However, the code path for service accounts bypasses this check, allowing token generation even when the account is marked as deactivated.
Attack Flow:
- An attacker obtains credentials for a service account (e.g., via credential theft, insider threat, or previous compromise).
- The legitimate owner deactivates the service account, believing access is revoked.
- The attacker continues to use the credentials to request new tokens from Zitadel's token endpoint.
- Zitadel issues a valid token, granting the attacker access to all resources the service account was authorized for.
- The attacker maintains persistent access until the credentials are rotated or the account is deleted.
Impact: This vulnerability undermines the deactivation security control, making it ineffective for service accounts. It can lead to prolonged unauthorized access, data exfiltration, and lateral movement within the organization's infrastructure.
Vulnerable vs. Patched Code
The vulnerability is in the token generation logic. The vulnerable code likely looks like this (pseudocode):
// Vulnerable version - missing deactivation check for service accounts
func (s *Server) generateToken(ctx context.Context, req *TokenRequest) (*Token, error) {
account, err := s.getAccount(req.AccountID)
if err != nil {
return nil, err
}
// Check deactivation only for user accounts, not service accounts
if account.Type == UserAccount && account.Deactivated {
return nil, ErrAccountDeactivated
}
// Generate token for both user and service accounts
token, err := s.tokenService.CreateToken(account)
return token, err
}
The patched version adds a deactivation check for service accounts:
// Patched version - includes deactivation check for all account types
func (s *Server) generateToken(ctx context.Context, req *TokenRequest) (*Token, error) {
account, err := s.getAccount(req.AccountID)
if err != nil {
return nil, err
}
// Check deactivation for all account types
if account.Deactivated {
return nil, ErrAccountDeactivated
}
// Generate token only if account is active
token, err := s.tokenService.CreateToken(account)
return token, err
}
The fix ensures that the deactivation flag is checked for both user and service accounts before token generation.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- Access to a Zitadel instance (e.g., a test environment).
- Credentials for a service account (e.g., client ID and client secret).
- Ability to deactivate the service account (or simulate deactivation).
Steps:
- Obtain Service Account Credentials: Assume you have a client ID and client secret for a service account.
- Deactivate the Service Account: In the Zitadel admin console, deactivate the service account.
- Request a Token: Use the credentials to request a token from the token endpoint:
curl -X POST https://your-zitadel-instance/oauth/v2/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET" - Verify Token Validity: The server returns a valid JWT token, even though the account is deactivated.
- Use the Token: Access protected resources using the token:
curl -H "Authorization: Bearer <token>" https://your-zitadel-instance/api/v1/protected-resource
Expected Result: The token is accepted, and the attacker gains unauthorized access.
Blue Team (Defense & Detection)
Detection Strategy:
- Monitor for token requests from deactivated service accounts. This is the primary indicator of exploitation.
- Alert on any successful authentication events for accounts with a
deactivatedstatus. - Review logs for repeated token requests from the same service account after deactivation.
Hunting Query (Splunk/ELK):
index=zitadel_logs sourcetype=token_request
| where account_type="service_account" AND account_status="deactivated"
| stats count by client_id, source_ip, timestamp
| where count > 1
Mitigation Steps:
- Immediately upgrade to a patched Zitadel version.
- Rotate all credentials for service accounts that were deactivated but may have been exploited.
- Delete deactivated service accounts instead of relying solely on deactivation.
- Implement additional monitoring for anomalous token usage patterns.
Indicators of Compromise (IOCs)
- Log Entries: Token generation events for service accounts with
deactivatedstatus. - Network Traffic: Repeated token requests from the same client ID after deactivation.
- Authentication Events: Successful authentication events for deactivated service accounts.
- Token Usage: JWT tokens with
sub(subject) claim matching a deactivated service account.
Example IOC Log Entry:
{
"timestamp": "2024-09-20T10:00:00Z",
"event": "token_generated",
"client_id": "service-account-123",
"account_status": "deactivated",
"grant_type": "client_credentials"
}
Detection Engineering
YARA Rule
rule CVE_2024_47000_Zitadel_Deactivation_Bypass {
meta:
description = "Detects log entries indicating token generation for deactivated service accounts in Zitadel"
author = "Valters IT"
date = "2024-09-20"
reference = "CVE-2024-47000"
severity = "high"
strings:
$log_pattern = /"account_status":\s*"deactivated"/ nocase
$token_event = /"event":\s*"token_generated"/ nocase
$service_account = /"client_id":\s*"[^"]+"/ nocase
condition:
all of them
}
Sigma Rule
title: Zitadel Token Generation for Deactivated Service Account
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects token generation events for deactivated service accounts in Zitadel logs
author: Valters IT
date: 2024-09-20
references:
- https://nvd.nist.gov/vuln/detail/CVE-2024-47000
logsource:
product: zitadel
service: token
detection:
selection:
event: "token_generated"
account_status: "deactivated"
account_type: "service_account"
condition: selection
falsepositives:
- Legitimate token generation before deactivation (race condition)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-47000 Zitadel Token Request for Deactivated Service Account"; flow:to_server; content:"POST"; http_method; content:"/oauth/v2/token"; http_uri; content:"grant_type=client_credentials"; http_client_body; content:"client_id"; http_client_body; content:"client_secret"; http_client_body; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Zitadel: Update to the latest patched version (2.62.1, 2.61.1, 2.60.2, 2.59.3, 2.58.5, 2.57.5, 2.56.6, 2.55.8, or 2.54.10).
- Rotate Credentials: For all service accounts that were deactivated, rotate their credentials (client secrets, API keys, passwords).
- Delete Unused Accounts: Instead of deactivating, delete service accounts that are no longer needed.
- Audit Logs: Review authentication logs for any unauthorized access from deactivated service accounts.
Long-Term Mitigations:
- Implement additional monitoring for service account activity.
- Use short-lived tokens and enforce token revocation.
- Regularly audit service account permissions and deactivation status.
- Consider using a separate identity provider for machine-to-machine authentication with stricter controls.
Workaround (if unable to patch):
- Instead of deactivating a service account, create new credentials and replace the old ones wherever they are used. Revoke all existing authentication keys and rotate the password. This effectively prevents the deactivated service account from being utilized.
Valters IT