CVE-2026-34171 Overview
Coolify is an open-source, self-hostable platform for managing servers, applications, and databases. A vulnerability in versions prior to 4.0.0-beta.471 allows an attacker to reset a victim's account password by tricking them into visiting a crafted invitation URL. The GET /invitations/{uuid} endpoint performs a state-changing password reset when the reset-password query parameter is present. An attacker with knowledge of a valid invitation UUID can force the victim's password to a predictable value derived from that UUID. The issue is tracked as [CWE-352] (Cross-Site Request Forgery) and is fixed in version 4.0.0-beta.471.
Critical Impact
An attacker can hijack a Coolify user account by causing the victim to visit a crafted invitation URL, resetting their password to the invitation UUID value.
Affected Products
- Coolify versions prior to 4.0.0-beta.471
- Self-hosted Coolify deployments exposing the /invitations/{uuid} endpoint
- Multi-tenant Coolify instances with pending team invitations
Discovery Timeline
- 2026-07-07 - CVE-2026-34171 published to NVD
- 2026-07-07 - Last updated in NVD database
Technical Details for CVE-2026-34171
Vulnerability Analysis
The vulnerability resides in the acceptInvitation method of the Coolify controller. The endpoint responds to GET requests and performs a state-changing operation when the reset-password query parameter is set. This violates the [CWE-352] safe-methods principle: GET requests must not modify server state. Because browsers automatically issue GET requests when a user clicks a link or loads an image tag, an attacker can trigger the password reset without any explicit form submission.
When the victim visits the crafted URL while authenticated, the controller updates the user's password to Hash::make($invitationUuid). The new password is deterministic and known to the attacker, because the attacker supplied the UUID. The force_password_reset flag is also toggled, but the attacker has already obtained working credentials.
Root Cause
The root cause is combining a state-changing action with an idempotent HTTP verb and using an attacker-controlled value as the new secret. The patch splits the endpoint into showInvitation (GET) and a separate POST handler for acceptance, removing the password reset side effect from the GET path entirely.
Attack Vector
The attacker must know or predict a valid invitation UUID and lure an authenticated victim to the crafted URL. Successful exploitation requires user interaction and produces a scope change, granting the attacker access to the victim's account and any teams they belong to.
// Vulnerable code removed in the patch (Controller.php)
- public function acceptInvitation()
- {
- $resetPassword = request()->query('reset-password');
- $invitationUuid = request()->route('uuid');
- $invitation = TeamInvitation::whereUuid($invitationUuid)->firstOrFail();
- $user = User::whereEmail($invitation->email)->firstOrFail();
-
- if ($invitationValid) {
- if ($resetPassword) {
- $user->update([
- 'password' => Hash::make($invitationUuid),
- 'force_password_reset' => true,
- ]);
- }
- }
- }
// Fixed: GET path renamed to showInvitation, no state changes
+ public function showInvitation()
Source: Coolify security patch commit 25d424c
Detection Methods for CVE-2026-34171
Indicators of Compromise
- Web server access logs showing GET requests to /invitations/{uuid}?reset-password=1 or similar query parameter values
- Database records where users.force_password_reset was set to true without a corresponding user-initiated reset workflow
- Authentication events from unfamiliar IP addresses immediately following an invitation URL visit
- Referer headers pointing to attacker-controlled domains preceding invitation endpoint hits
Detection Strategies
- Review Coolify application logs for GET requests to the invitation endpoint that include the reset-password query parameter
- Correlate TeamInvitation UUIDs with subsequent password change events on associated user accounts
- Alert on password hash changes for accounts that did not initiate a password reset through the standard flow
Monitoring Recommendations
- Monitor the users table for unexpected changes to password and force_password_reset columns
- Log and alert on outbound links in emails or chat platforms that match the /invitations/*?reset-password pattern
- Track invitation UUID enumeration attempts against the Coolify web tier
How to Mitigate CVE-2026-34171
Immediate Actions Required
- Upgrade all Coolify instances to version 4.0.0-beta.471 or later
- Invalidate all outstanding team invitations issued before the upgrade
- Force password resets for accounts that had pending invitations during the vulnerable window
- Audit team memberships for unexpected additions tied to attacker-controlled emails
Patch Information
The fix is available in Coolify release v4.0.0-beta.471. The patch commit 25d424c743d5134d4a005a6d8f754bb3235b632c splits the invitation endpoint into a read-only GET handler (showInvitation) and a state-changing POST handler (acceptInvitation). See the GitHub Security Advisory GHSA-389w-cc6x-wr2m for the full advisory.
Workarounds
- Restrict access to the Coolify web interface to trusted networks or via VPN until the patch is applied
- Disable the invitation feature temporarily by removing pending TeamInvitation records from the database
- Instruct users to log out of Coolify before clicking any invitation link received from an unverified source
# Verify the running Coolify version and upgrade
docker exec coolify sh -c 'cat /var/www/html/versions.json'
# Pull the fixed release and restart
cd /data/coolify/source
git fetch --tags
git checkout v4.0.0-beta.471
docker compose pull
docker compose up -d
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

