Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-42172

CVE-2026-42172: Coolify Auth Bypass Vulnerability

CVE-2026-42172 is an authentication bypass flaw in Coolify where Sanctum API tokens never expire, allowing leaked tokens to retain access indefinitely. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-42172 Overview

Coolify is an open-source, self-hostable platform for managing servers, applications, and databases. Versions prior to 4.0.0-beta.474 issue Laravel Sanctum API tokens that never expire. A leaked or stolen token therefore retains full API access indefinitely until an administrator manually revokes it. The flaw is tracked under [CWE-613: Insufficient Session Expiration] and is fixed in Coolify 4.0.0-beta.474.

Critical Impact

Leaked Coolify API tokens grant persistent, unbounded access to server, application, and database management operations until manually revoked by an administrator.

Affected Products

  • Coolify versions prior to 4.0.0-beta.474
  • Deployments using Laravel Sanctum-issued Personal Access Tokens
  • Self-hosted Coolify instances exposing the API to network clients

Discovery Timeline

  • 2026-07-07 - CVE-2026-42172 published to the National Vulnerability Database (NVD)
  • 2026-07-07 - Last updated in NVD database

Technical Details for CVE-2026-42172

Vulnerability Analysis

Coolify authenticates API clients using Laravel Sanctum Personal Access Tokens. Prior to 4.0.0-beta.474, the application created these tokens without setting an expires_at timestamp. As a result, every token remained valid indefinitely.

An attacker who obtains a token through log leakage, backup exposure, developer machine compromise, or accidental commit to a public repository can continue to authenticate against the Coolify API. Access persists across password rotations and user session logouts because Sanctum bearer tokens are decoupled from interactive sessions. The token can be used to deploy applications, read secrets, and manage connected servers and databases.

The issue is a configuration and design flaw in session lifecycle management rather than a code execution or memory corruption bug. Exploitation requires the attacker to already possess a valid token, which is reflected in the low privileges required attack profile.

Root Cause

The root cause is missing token expiration logic. Sanctum supports token expiration through the sanctum.expiration configuration value and the optional expiresAt parameter on createToken(), but Coolify did not use either mechanism. Without an expiration boundary, no automatic invalidation occurred, violating the principle of limited credential lifetime.

Attack Vector

Exploitation is network-based. An attacker who acquires a leaked API token sends an authenticated HTTP request to the Coolify API using the Authorization: Bearer <token> header. Because the token never expires, the request succeeds long after the token was originally issued. There is no user interaction required, and the operation runs with the privileges of the account that generated the token.

php
// Security patch: expiration warning job introduced in the fix
// Source: https://github.com/coollabsio/coolify/commit/b1a78df58efe3ac38679d18c888b5817c7f01216
<?php

namespace App\Jobs;

use App\Models\PersonalAccessToken;
use App\Models\Team;
use App\Models\User;
use App\Notifications\ApiTokenExpiringNotification;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\RateLimiter;
use Laravel\Horizon\Contracts\Silenced;

class ApiTokenExpirationWarningJob implements ShouldBeEncrypted, ShouldQueue, Silenced
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 1;

    public $timeout = 120;

    public function handle(): void
    {
        PersonalAccessToken::query()
            ->whereNotNull('expires_at')
            ->where('expires_at', '>', now());
    }
}

The patch introduces ApiTokenExpirationWarningJob and populates expires_at on the personal_access_tokens table so Sanctum can enforce token lifetime. See the GitHub Commit Details for the full change set.

Detection Methods for CVE-2026-42172

Indicators of Compromise

  • API requests authenticated with tokens issued months earlier and still returning HTTP 200 from the Coolify API
  • Rows in the personal_access_tokens table with NULL values in expires_at and last_used_at timestamps far in the past
  • Unexpected source IP addresses appearing in Coolify web server access logs with valid bearer authentication
  • Access to sensitive endpoints such as /api/v1/servers, /api/v1/applications, or /api/v1/deploy from unfamiliar user agents

Detection Strategies

  • Query the personal_access_tokens table for records where expires_at IS NULL to inventory long-lived credentials
  • Correlate the tokenable_id field with recent authentication events to identify tokens still in active use
  • Search Git history, chat logs, and CI/CD variables for strings matching the Sanctum token format <id>|<40-char-secret>
  • Enable Laravel HTTP request logging on the API routes and flag bearer token reuse from multiple IP addresses within short windows

Monitoring Recommendations

  • Forward Coolify application logs and reverse proxy access logs to a centralized logging or SIEM platform for retention and alerting
  • Alert on any Coolify API response with status 2xx where the presented token has an expires_at value of NULL
  • Track geographic and network origin drift for tokens tied to specific service accounts and CI systems
  • Review notifications table entries generated by ApiTokenExpiringNotification after upgrade to confirm the new job is running

How to Mitigate CVE-2026-42172

Immediate Actions Required

  • Upgrade all Coolify instances to 4.0.0-beta.474 or later without delay
  • Revoke every existing Sanctum token after the upgrade and reissue tokens with an explicit expiration date
  • Audit external systems, scripts, and CI pipelines that store Coolify tokens and rotate any credentials suspected of exposure
  • Restrict network access to the Coolify management API using firewall rules or a reverse proxy allowlist

Patch Information

The fix is delivered in Coolify 4.0.0-beta.474. The release adds an expires_at column enforcement path and the ApiTokenExpirationWarningJob background job to notify users before tokens lapse. Review the GitHub Security Advisory GHSA-c83f-5ph7-x8xv, the GitHub Pull Request Discussion, and the GitHub Release v4.0.0-beta.474 for full details.

Workarounds

  • Manually revoke unused or aged tokens through the Coolify UI or by deleting the corresponding rows from the personal_access_tokens table
  • Set a short SANCTUM_EXPIRATION value in the Coolify environment configuration and restart the queue workers
  • Place the Coolify API behind a VPN or zero-trust proxy so that a leaked token alone cannot reach the endpoint
  • Enforce token scoping so each token receives only the abilities required for its automation task
bash
# Configuration example: enforce a 30-day (43200 minute) Sanctum token lifetime
# Add to the Coolify .env file, then restart the application and queue workers
SANCTUM_EXPIRATION=43200

# Verify configuration is applied
php artisan config:clear
php artisan config:cache
php artisan queue:restart

# Revoke all existing long-lived tokens (run inside tinker)
php artisan tinker --execute="\App\Models\PersonalAccessToken::whereNull('expires_at')->delete();"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.