CVE-2026-78699: rename_tenant returns :ok on a failed rename, enabling cross-tenant access in AshPostgres
Unchecked Return Value vulnerability in ash-project ashpostgres allows a user who can drive a tenant rename to a name that collides with an existing tenant's schema to have their tenant record repointed at that other tenant's live schema, gaining access to its data.
AshPostgres.MultiTenancy.renametenant/3 issues the ALTER SCHEMA ... RENAME TO ... with the non-raising Ecto.Adapters.SQL.query/2, discards its {:ok, } | {:error, } result, and unconditionally returns :ok. PostgreSQL rejects the rename when the target schema already exists (and on insufficient privilege or lock timeout), but that failure never reaches the caller. The calling managetenant update action therefore sees success and commits the tenant row with the new name, which is the schema of a different existing tenant, so subsequent reads and writes for that tenant run against the other tenant's data.
This issue affects ashpostgres: from 0.25.0 before 2.13.0.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
ash-project ash_postgresto a version that resolves this vulnerability.Fixed in 2.13.0 - Operational
Ensure rename_tenant/3 checks the result of the underlying Ecto.Adapters.SQL.query/2 call (do not discard {:ok, _} | {:error, _}); return/propagate failures instead of unconditionally returning :ok when ALTER SCHEMA RENAME TO ... fails (e.g., target schema already exists, insufficient privilege, or lock timeout).
Event History
Frequently Asked Questions
Which ash_postgres versions are affected?
The issue affects ash_postgres versions from 0.25.0 before 2.13.0.
Who can exploit this issue?
An attacker needs the ability to drive a tenant rename and choose a target name that matches an existing tenant schema. The PostgreSQL schema rename must fail because that target schema already exists; the application then treats the failed operation as successful.
How can I check whether a tenant may already have been repointed?
Look for tenant rename operations where the tenant record was updated to a schema name already used by another tenant, despite the corresponding ALTER SCHEMA rename failing. PostgreSQL failures caused by an existing target schema, insufficient privileges, or lock timeouts are not propagated by the affected rename function.