← Back to Feed CACHED · 2026-06-30 15:18:33 · CACHE_KEY CVE-2026-34592
CVE-2026-34592 · CWE-639 · Disclosed 2026-06-29

Coolify is an open-source and self-hostable tool for managing servers

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A self-hosted Heroku clone forgot to check whose tenant you're in before handing over the server list

Coolify is an open-source PaaS that manages servers, applications, databases, and deployments — think Heroku/Vercel you run yourself. In versions prior to 4.0.0-beta.471, the server and project lookup endpoints fail to scope queries to the requesting user's team_id. Any authenticated user with a valid session can substitute another team's server ID or project ID into the URL and read that team's resources back. CWE-639 — classic Authorization Bypass Through User-Controlled Key (IDOR). CVSS vector AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N reflects confidentiality-only impact but with scope change, because the data crossing the boundary belongs to a different security principal (another team).

Vendor severity HIGH (7.7) is fair *for the multi-tenant deployments that are actually affected*. The catch: most Coolify installs in the wild are single-team (a solo dev or small shop running their own apps), so the population at risk is the subset of Coolify operators who invite users from outside their trust boundary — agencies hosting client environments, internal platform teams hosting multiple product squads, etc. For those operators, the leak isn't theoretical: project objects in Coolify carry environment variables, repo URLs, and references to server connection profiles that hold SSH credentials. That's why we keep this at HIGH despite the auth requirement.

"Cross-tenant IDOR on a PaaS that brokers SSH keys and deploy secrets — auth-gated but the blast radius is every other team's project metadata."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Obtain any authenticated session on the target Coolify instance

Attacker registers (if registration is open) or is invited as a low-privileged member of any team on the target Coolify instance. PR:L in the CVSS vector means a session cookie / API token is all that's required — no admin role, no team-owner role.
Conditions required:
  • Coolify instance reachable on the network the attacker is on
  • Open registration OR existing low-priv account in any team
Where this breaks in practice:
  • Most production Coolify instances are behind VPN or basic auth proxy
  • Self-hosted PaaS rarely has open registration — would-be tenant must be invited
Detection/coverage: Authentication logs in Coolify's PostgreSQL store; reverse-proxy access logs if Caddy/Traefik fronts it.
STEP 02

Enumerate other teams' resource IDs

Coolify uses incrementing or UUID-style identifiers for servers (/servers/{id}) and projects (/projects/{uuid}). Attacker scripts a sequential walk (for integer IDs) or harvests UUIDs from prior responses, leaked references, or shared CI runs. Standard curl + jq loop; no custom tooling.
Conditions required:
  • Knowledge of the API surface (documented at coolify.io/docs)
  • ID format is enumerable or guessable
Where this breaks in practice:
  • UUIDs reduce blind enumeration to oracle-style attacks
  • Rate limiting at the reverse proxy slows mass walks
Detection/coverage: Spike in 200-OK responses to /servers/* and /projects/* from a single session is the telltale; default Coolify telemetry does NOT alert on this.
STEP 03

Read cross-team server and project objects via direct ID reference

The vulnerable lookup paths execute Server::find($id) / Project::find($uuid) without the whereHas('team', currentTeam()) scope. Authenticated request to another team's resource returns 200 with full object — including server hostname, IP, connection settings, project name, repo URL, and references to associated environment variables and deployments.
Conditions required:
  • Target IDs from step 2
  • Bug present (i.e., target < 4.0.0-beta.471)
Where this breaks in practice:
  • The advisory specifies *server and project lookups* — secret/env-var endpoints may be separately scoped. Confirm what your version actually leaks before treating as 'full env-var exposure'.
Detection/coverage: Application-layer logging would show user_id from team A accessing resources owned by team B. Coolify does not log this by default; build it in front of the Nginx/Caddy proxy.
STEP 04

Pivot from leaked metadata to deployment compromise

With another team's server hostname, repo URL, and project structure, attacker can target the upstream Git repository (steal credentials, submit malicious PRs), brute-force or social-engineer SSH access to the managed server, or correlate exposed deployment data with other intel for a follow-on attack. This step is OUT of the CVE itself but is the realistic blast radius on a multi-tenant agency or platform-team install.
Conditions required:
  • Useful intel returned in step 3
  • Reachable target server or upstream repo
Where this breaks in practice:
  • MFA on Git provider
  • SSH key-based auth on managed servers (default Coolify config) prevents direct hostname-only pivot
Detection/coverage: GitHub/GitLab audit logs for unusual repo enumeration; SSH auth-failure logs on managed servers.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone reported as of 2026-06-30. No GreyNoise tags, no campaigns, no incident reports.
Public PoCGitHub Security Advisory GHSA (coollabsio/coolify) describes the flaw; no weaponized PoC repo observed but the bug is trivially reproducible with curl once you have any session.
EPSSNot yet scored (CVE published 2026-06-29). Expect <1% within 30 days given auth requirement and lack of mass exposure.
KEVNot listed. Unlikely to be added — confidentiality-only, auth-gated, narrow population.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N → 7.7 HIGH. Scope change reflects cross-tenant boundary. No I or A impact in the CVE itself.
Affected versionsAll Coolify releases prior to 4.0.0-beta.471.
Fixed version4.0.0-beta.471 and later. No distro backports — Coolify ships as Docker images via coollabsio/coolify.
Exposure dataShodan/Censys queries for coolify favicon hash typically return ~2,000–5,000 public Coolify dashboards globally. Of these, the subset that are multi-team is the real attack surface — likely a small minority.
Disclosed2026-06-29 via coollabsio GitHub Security Advisory.
ReporterCoordinated disclosure via Coolify maintainers (coollabsio). Researcher attribution per the GHSA advisory.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.0/10)

Reassessed HIGH because the single decisive factor is the role multiplier: the affected component is an orchestration plane that brokers SSH keys, environment variables, and Git credentials — leaking another team's project metadata is a credible step toward fleet compromise on multi-tenant installs. The auth requirement (PR:L) and confidentiality-only impact prevent escalation to CRITICAL.

HIGH Vulnerability mechanics and fixed version
MEDIUM Realistic blast radius — depends on which lookup endpoints leak which fields in your version
HIGH Population at risk is the multi-tenant subset of Coolify operators

Why this verdict

  • Auth-gated (PR:L): the attacker must already hold a valid session on the target instance. That eliminates the drive-by-internet population.
  • Single-tenant installs are unaffected in practice: if your Coolify only has one team, there is no other team to enumerate. The bulk of self-hosted Coolify deployments fall here.
  • Role multiplier — orchestration platform: Coolify is a deployment broker holding SSH connection profiles, env vars, and Git creds. Cross-tenant read on Server and Project objects can hand an attacker enough metadata to pivot to managed hosts. This is the reason we hold at HIGH instead of dropping to MEDIUM.
  • No I or A impact in the CVE itself: the chain ends at *read* of another team's resources. Modification, deletion, deploy-time RCE, and direct credential theft would require a chained second bug or are scope-limited to what the lookup returns.
  • No KEV, no PoC weaponization, no campaign telemetry: purely a hygiene patch on the timeline the SLA dictates.

Why not higher?

Not CRITICAL because PR:L (authentication required), no integrity or availability impact, and the population that is actually multi-tenant is a minority of Coolify deployments. CRITICAL would require unauthenticated reachability or direct RCE/credential-theft impact on the typical install.

Why not lower?

Not MEDIUM because Coolify is canonically a high-value-role component (deployment orchestration with secret material). On the subset of installs that ARE multi-tenant (agencies, internal platform teams), the chain credibly extends from metadata read to managed-server pivot. Generic CWE-639 on a CRUD app would be MEDIUM; on a PaaS it earns the role multiplier.

05 · Compensating Control

What to do — in priority order.

  1. Upgrade to Coolify 4.0.0-beta.471 or later — The only complete fix. Pull the new coollabsio/coolify image, run the documented upgrade flow. Per noisgate remediation SLA, complete within 180 days; for multi-tenant installs treat as ≤ 30 days.
  2. Audit team membership and revoke unused accounts — The bug requires *any* authenticated session. Cull dormant invitees and former contractors today. This is the cheapest compensating control and within the noisgate mitigation SLA of 30 days for HIGH.
  3. Restrict Coolify dashboard to VPN / SSO-gated reverse proxy — If your instance is reachable on the public internet, front it with Cloudflare Access, Tailscale, or an SSO-aware reverse proxy. Deploy within 30 days to satisfy the mitigation SLA.
  4. Enable application-layer audit logging for /servers/* and /projects/* — Use the reverse proxy to log requested IDs alongside the session's user_id. Run a daily diff: any access where the project's owning team ≠ the requester's team is the exploit signature. Stand up within the 30-day window.
  5. Rotate SSH keys and env-var secrets stored in Coolify if multi-tenant — Assume leaked. Rotate before the next billing cycle. This is a remediation step, not a control — but a multi-tenant install that defers rotation is gambling on no prior exploitation having happened.
What doesn't work
  • WAFs / generic IDS rules: the request is structurally identical to a legitimate one — same path, same method, same headers, valid session cookie. Only the resource ID differs. No signature catches this.
  • MFA: doesn't help — the attacker IS authenticated. MFA gates session creation, not authorization scope inside the app.
  • Network segmentation alone: if all teams reach the same Coolify URL, segmentation doesn't prevent the IDOR. Per-team Coolify instances would, but that's a re-architecture, not a control.
06 · Verification

Crowdsourced verification payload.

Run this from an auditor workstation with shell access to the Coolify host (or anywhere docker can reach the running container). Invoke as ./check_coolify.sh <coolify_container_name_or_id> — example: ./check_coolify.sh coolify. No special privileges beyond being in the docker group.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verification: CVE-2026-34592 — Coolify cross-team IDOR
# Outputs: VULNERABLE / PATCHED / UNKNOWN
set -u

CONTAINER="${1:-coolify}"
FIXED="4.0.0-beta.471"

if ! command -v docker >/dev/null 2>&1; then
  echo "UNKNOWN — docker CLI not available"
  exit 2
fi

if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then
  echo "UNKNOWN — container '$CONTAINER' not found"
  exit 2
fi

# Extract version from the running container. Coolify exposes /api/health and writes
# a versions.json; fall back to image tag.
VER="$(docker exec "$CONTAINER" sh -c 'cat /var/www/html/versions.json 2>/dev/null | grep -oE "\"coolify\"\s*:\s*\"[^\"]+\"" | head -1 | sed -E "s/.*:\s*\"([^\"]+)\".*/\\1/"' 2>/dev/null)"

if [ -z "$VER" ]; then
  VER="$(docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.version" }}' "$CONTAINER" 2>/dev/null)"
fi

if [ -z "$VER" ]; then
  VER="$(docker inspect --format '{{.Config.Image}}' "$CONTAINER" | awk -F: '{print $2}')"
fi

if [ -z "$VER" ]; then
  echo "UNKNOWN — could not determine Coolify version"
  exit 2
fi

# Lexicographic compare works for Coolify's semver-ish 4.0.0-beta.NNN scheme
# Normalize: strip leading 'v'
VER="${VER#v}"

verlte() { [ "$(printf '%s\n%s' "$1" "$2" | sort -V | head -n1)" = "$1" ]; }

if verlte "$FIXED" "$VER"; then
  echo "PATCHED — Coolify $VER (fixed in $FIXED)"
  exit 0
else
  echo "VULNERABLE — Coolify $VER < $FIXED — upgrade to $FIXED or later"
  exit 1
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: identify every Coolify instance in your estate and check whether it has more than one team configured. Single-team installs are not at meaningful risk — schedule the upgrade as routine hygiene within the noisgate remediation SLA of 180 days for HIGH. Multi-team installs (agencies, internal platform teams hosting multiple squads) need to move fast: apply the noisgate mitigation SLA of ≤ 30 days by either upgrading to Coolify 4.0.0-beta.471, fronting the dashboard with SSO/VPN, or culling the team membership down to a single trust boundary; complete the actual upgrade within the 90-day remediation window even though SLA permits 180. Rotate any SSH keys and env-var secrets that are stored in a multi-team Coolify instance — assume they've been read. No KEV listing, no campaign activity, so no need to declare an incident — but don't let this one slide because the CVSS doesn't have an A impact: on a PaaS, metadata leakage is the on-ramp to the credential leakage you actually care about.

Sources

  1. Coolify GHSA — coollabsio/coolify Security Advisories
  2. Coolify project — coollabsio/coolify GitHub
  3. CWE-639: Authorization Bypass Through User-Controlled Key
  4. The Hacker News — Coolify Discloses Critical Flaws
  5. heise online — Coolify critical vulnerabilities
  6. wz-it — Coolify CVE Overview 2025/2026
  7. Coolify documentation
  8. FIRST CVSS 3.1 specification
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.