Zeabur's Second Breach Ran on Keys the First Rotation Missed
Zeabur, a Taiwanese PaaS, is shutting down on December 31 after two breaches in two months. The October attacker used plaintext admin tokens and AWS keys that were never rotated after August to reach shared clusters in nine regions and the platform database. We separate what is confirmed from what is still a hypothesis, list what users should do, and turn the root causes into a checklist for other teams.


On this page(11)
Two breaches, then a shutdown
On October 17, 2026, Zeabur announced it is winding down. From December 1, dedicated server renewals stop and shared cluster services are paused; on December 31, every server and cluster goes dark. The founder named limits to growth, a system that had become hard to maintain, and this year's two security incidents.
The second incident began at 01:36 UTC on October 14. Using Zeabur's own internal credentials, the attacker reached shared clusters in nine regions, AWS, and some GCP Dedicated Servers, and finally read the platform database. That database held 3,218,965 environment variable records and details for 321,810 accounts. No alert fired. The investigation began at 13:56 on October 15, after a user report, about 36 hours after the first credential was used.
One fact matters more than the rest. The admin tokens and AWS keys used in October were left out of the rotation after August. Zeabur's August report said "all internal admin keys have been disabled or rotated"; its October report corrects that statement as incomplete.
What is confirmed, and what is still a hypothesis
Confirmed in Zeabur's reports (preliminary report of October 19, 2026):
- The shared cluster admin token was created on January 10, 2024, with no expiry. Since January 2026 it sat in plaintext in a private configuration repository.
- Internal AWS keys sat in plaintext in the same repository. Neither was rotated after August.
- The cluster admin interface was reachable from the public internet.
- GCP Dedicated Server root passwords were in plaintext in the server initialization settings. They were found on September 3 and not fixed before the incident.
- The attacker signed in as root to 101 GCP Dedicated Servers belonging to 92 users, added SSH keys to 50 of them, and attached 16 copies of customer server disks to their own VMs.
- Commands ran against 865 database services on the shared cluster. Of 607 n8n instances checked, 602 kept their encryption key in an environment variable.
- Projects that moved their environment variables to their own Dedicated Servers after August, as Zeabur advised, were outside the platform database read.
Still a hypothesis:
- How the attacker got the configuration repository credentials is not confirmed. Zeabur's leading candidate is the GitHub App private key leaked in August, but the attacker IPs from the two incidents do not overlap, and Zeabur is waiting on audit records from GitHub.
- Whether the anonymous probing on October 10–13 and the SSH attempts came from the same attacker is unproven.
- Whether the abuse of a user's OpenAI key on October 16 (about 1,107 requests) came from this leak is a hypothesis.
August: from a NextChat container to an AWS root key
The August 27 incident began in NextChat v2.16.1, which a customer had deployed on the shared cluster. An authorization flaw in its MCP feature (CVE-2026-7644) gave the attacker code execution in the container. From there the shared cluster's internal network led to a routing cache. The cache existed to map domains to services, but it also held Zeabur Legacy API Keys. The attacker tried them one by one and found a team administrator's key.
That key read the environment variables of an internal management service, which held several AWS keys, including a long-retained root key. A maintenance job's database credential, with more permissions than the job needed, then opened the production database: account information and project environment variables, including customers' third-party API keys, cloud credentials, database passwords and signing keys.
Every hop across those four boundaries used a non-human credential: an API key in a cache, a cloud key in a service's environment, a database account attached to a job.
October: the credentials outside the rotation list
After August, Zeabur rotated the internal keys it had confirmed as leaked, turned off Legacy API Key authentication, and told users to rotate their variables and move them to Dedicated Servers. The rotation was scoped to keys known to be leaked. The cluster admin tokens and AWS keys in plaintext in the configuration repository, and the root passwords in the GCP initialization settings, were not on that list. October's attack ran on exactly those three.
The attack ran down two paths and then joined them.
- Shared cluster and AWS. The AWS keys were first used at 01:36 and a cluster admin token at 01:40. By 12:39 the attacker had read the settings and secrets of every service on the shared cluster. A key meant for one bucket could read every bucket in the account; Zeabur assesses the attacker used it to read an old cluster backup. That backup held a key for the secrets management service, which the attacker used to read about 53 production secrets, including internal network admin credentials, a platform database account and the GitHub App private key.
- GCP Dedicated Servers. From 13:40 on October 14, the plaintext root passwords opened 101 servers. At 15:05 on October 15, the attacker also obtained a production GCP key.
- The join. At 15:30 on October 15, the attacker used the internal network admin credentials from the first path to add a compromised GCP server as a node on Zeabur's internal network. The network rules let that node reach the platform database, and a "read-only" account that could read everything did the rest, from 16:10 to 16:47.
The same pattern showed up once more during the response. A 16:00 backup captured some credentials that had just been rotated, and the attacker used one of them at 20:30. The last observed attacker activity was at 21:05 on October 15, in AWS.
This is not just Zeabur's problem
Read Zeabur's own list of root causes and most of it maps onto patterns from our NHI Kill Chain series.
- Aged Key. The cluster admin token lived from January 2024 with no expiry and no rotation. The attacker had its entire lifetime to work with.
- Out of Scope Loophole. The August rotation was scoped to keys confirmed as leaked. Plaintext credentials spread across a configuration repository, code, build jobs, server initialization settings and backups sat outside that scope. A key that is not in the inventory does not get rotated.
- Over-shared Key and excess permissions. A single-bucket key read every bucket, the default GCP service account could write to the project, and a read-only database account could read all data. Permissions set the blast radius when one key leaks.
- Ghost Key. A deploy key for a decommissioned service stayed valid for four months after shutdown, and read the configuration repository at 15:02 on October 15 (assessed as the attacker).
- Backups that carry secrets. Backups held every secret, and the backup access key sat next to the other secrets. Even freshly rotated values were captured by the next backup.
- Detection. More than 16 hours of attacker activity raised no alert. Storage, GCP and GitHub access logs were incomplete, so part of what actually left is still unknown.
The hardest lesson here is how far to scope rotation after an incident. "Rotate what we know leaked" sounds reasonable, but when you do not know how far the attacker saw, scope it to everything the attacker could have reached. That requires knowing which keys live inside that reach in the first place.
If you use Zeabur, do this now
This follows Zeabur's guidance, in order. With the shutdown dates fixed, rotate and migrate together.
- Rotate every credential in your environment variables. API keys, cloud keys, database passwords, signing and encryption keys. Revoke at the issuer first, then create new values and redeploy. Projects moved to a Dedicated Server after August still need rotation if that server is a compromised host.
- Passwords and tokens inside databases. Changing an environment variable does not change the password inside the database. Change database user passwords and revoke sessions, tokens and hashes stored in the database.
- n8n. Replace the encryption key and recreate every third-party credential. Almost every n8n instance checked kept its encryption key in an environment variable.
- new-api/one-api. Revoke upstream AI keys and reissue access tokens.
- GCP Dedicated Servers. Treat them as compromised: back up and rebuild. If you cannot rebuild yet, remove keys commented
@zeabur-pentestfrom/root/.ssh/authorized_keys, check crontab, systemd and k3s workloads, change the root password, and turn off SSH password login. - GitHub. Check your audit log for Zeabur GitHub App clones or pushes, new deploy keys and webhook changes between 15:05 and 18:54 UTC on October 15.
- Bills. Check charges at each issuer from October 14. GCP Dedicated Server users should check from September 1.
- Migration. Shared cluster services pause and Dedicated Server renewals stop on December 1. Finish backups and migration before each server's expiry date.
As you rotate, find every place the same value was copied. If a key in your Zeabur variables also lives in CI, a local .env or another cloud's settings, changing it in Zeabur alone does not finish the job.
Checks for teams that never used Zeabur
Most of these causes exist at companies that do not run a deployment platform. Check whether your team has any of these:
- Admin tokens or cloud keys with no expiry. Can you say when each was created and last rotated?
- Credentials in plaintext in private repositories, infrastructure config, server bootstrap scripts or build jobs. "It's private" fails the moment one person's repository access leaks.
- Backups that contain secrets as-is, with the key that opens them stored next to the other secrets.
- Deploy keys, webhook tokens and service accounts for services you have shut down.
- Permissions wider than the name suggests. What can the "read-only" database account actually read? How many buckets does the one-bucket key open?
- Your last post-incident rotation list. If you rotated only the keys confirmed as leaked, check whether the rest from the same systems are still valid.
What Cremit can and cannot see
We cannot see Zeabur's internal configuration repository or platform database. Whether a specific key of yours was read from Zeabur's database is a question for Zeabur's report and each issuer's usage records.
Cremit Platform works on your side. It finds credentials exposed in connected repositories and on public surfaces, checks whether each one still works at its issuer, and puts them in one inventory alongside secrets from stores such as AWS Secrets Manager, GCP Secret Manager and HashiCorp Vault. That inventory shows the cloud key sitting in plaintext in a private repository, the key created years ago that still authenticates, and the value copied to several places. When an incident hits, answering "what was within the attacker's reach" starts with that list.
Scope rotation to the attacker's reach
After August, Zeabur rotated the keys it had confirmed and left the others in place. The October attacker came in through what was left. The shutdown had more than one cause, but the second breach came from the gaps in a rotation list.
After an incident, scope rotation to every key within the attacker's reach, not only the ones you have confirmed as leaked.
Sources
- Zeabur, October 2026 security incident (preliminary report), 2026-10-19: https://zeabur.com/blogs/october-2026-security-incident
- Zeabur, August 2026 security incident: https://zeabur.com/blogs/august-2026-security-incident
- Zeabur, Zeabur is shutting down, 2026-10-17: https://zeabur.com/blogs/zeabur-is-shutting-down
- BleepingComputer, Zeabur shutting down after second security breach in two months, 2026-10-20: https://www.bleepingcomputer.com/news/security/zeabur-shutting-down-after-second-security-breach-in-two-months/
Related reading
Read next
One API key in three repositories: investigating shared credentials
Three observed locations are not a complete dependency map. Check key type, issuer status, permissions, and actual consumers before replacement.
Long-exposed credentials: what a 90-day source record tells you
An old source record and an active key do not establish key age. Check when the value appeared, issuer status, permissions, and dependencies.
The machine access behind an exposed API key
An exposed key is a lead. Connect it to its issuer, principal, permissions, workload, and owner before closing the access path.
Get the next one in your inbox
Monthly NHI security brief from Cremit. One email, high signal.