Quick Answer
On 14 and 15 October 2026 an attacker got into Zeabur, an app hosting platform, and read 3,218,965 environment variable records, the place where apps keep their API keys and database passwords. Zeabur's own report says the way in was its own admin keys, stored in plaintext in a private repository. Zeabur is shutting down by 31 December 2026. If you ever deployed there, replace every secret you stored on it, even if you already did after its August incident.
What the Attacker Took
Zeabur published a detailed preliminary report on 19 October. Credit where it is due: it is unusually specific about what went wrong. All numbers below come from that report.
| What | How much | Status in the report |
|---|---|---|
| Environment variable records (names and values) | 3,218,965 | Confirmed read from the platform database |
| Accounts (email, username, phone number) | 321,810 | Confirmed read |
| Dedicated servers with root sign-ins | 101 servers of 92 users | All treated as compromised, SSH keys added on 50 |
| User database services where commands ran | 865, including 736 n8n and 211 PostgreSQL | Output not logged, so what was taken is unknown |
| Copies of customer server disks | 16, attached to 5 attacker-made machines | Confirmed |
| Zeabur's internal production secrets | About 53, including its GitHub App private key | Read, no use of the GitHub key found so far |
The report also says the attacker read the login signing key and likely forged logins, and downloaded at least one customer database backup. Zeabur rotated the signing key and signed out every user.
How They Got In
This is the part every founder should read twice. According to Zeabur, the attacker used Zeabur's AWS keys and cluster admin tokens that were stored in plaintext in a private configuration repository. The cluster admin interface could be reached from the public internet, and the tokens never expired. Zeabur says it has not confirmed how the attacker got those credentials.
The dedicated servers fell the same way. Zeabur assesses that root passwords were stored in plaintext in server set-up settings, and were reached with an old cloud key. From one compromised server the attacker joined Zeabur's internal network and read the platform database.
None of this needed a clever exploit. Each step used a secret that was written down in plain text, never expired and worked from anywhere. The same pattern is easy to build into any app: a config/production.yaml or .env in a private repo, holding keys that have never been rotated.
# BAD: long-lived keys in plaintext, in a "private" repo
cloud:
access_key_id: "<real key here>"
secret_access_key: "<real secret here>"
cluster:
admin_token: "<token that never expires>"
A private repository is still a copy of your secrets, on every laptop that cloned it and in every tool that can read it. "Private" limits who should see it. It does not stop a leaked token, a stolen laptop or a compromised integration.
The August Incident: Another Customer's App Was the Door
October was Zeabur's second breach of 2026. Its August incident report, dated 7 September, says unauthorised access began on 27 August. The way in was not Zeabur's own code. The attacker exploited a NextChat v2.16.1 service that one user had deployed on a shared cluster, which Zeabur links to CVE-2026-7644, an authorisation flaw in its MCP feature.
From inside that container, the attacker reached the cluster's routing cache over the internal network. The cache held Zeabur Legacy API Keys, and one belonged to a team administrator. That key read the environment variables of an internal management service, which held an AWS root key, and from there the attacker reached the production database. Zeabur says bulk reads of project environment variables began at 11:52 UTC on 27 August.
Two lessons follow. On shared hosting, a neighbour's unpatched app can be the first step into your data. And every app you deploy yourself, a chat UI included, needs updates like any other software. After August, Zeabur disabled Legacy API Keys and says its current access tokens are scoped, expire and keep access records.
One Thing That Limited the Damage
Zeabur's report shows how much storage choices matter after a breach. Its 11,536 platform Access Tokens were stored as irreversible hashes, so reading the database did not hand the attacker working tokens, and all of them were revoked anyway. Its 566 zSend API keys were stored in plaintext, so they had to be treated as stolen and were revoked.
If your app issues API tokens to its own users, the same rule applies. Show the token to the user once, and store only a hash of it.
// GOOD: a stolen database copy holds only hashes, not working tokens
import { createHash, randomBytes } from 'node:crypto';
const token = randomBytes(32).toString('hex');
const tokenHash = createHash('sha256').update(token).digest('hex');
await db.query('INSERT INTO api_tokens (user_id, token_hash) VALUES ($1, $2)', [userId, tokenHash]);
To check a token later, hash what the client sends and compare it with the stored hash.
If You Used Zeabur: What to Do Now
Zeabur's report lists these steps. In short:
- Replace every credential in your environment variables: API keys, cloud keys, database passwords and signing or encryption keys. Revoke the old key with the provider first, then redeploy. Zeabur says this applies even if you rotated after August.
- Change passwords inside your databases if you used the shared cluster. Changing the Zeabur environment variable does not change the password in the database itself.
- n8n users: replace the encryption key and recreate every stored third-party credential.
- new-api or one-api users: revoke the upstream AI keys and make new access tokens.
- Dedicated server users: treat the server as compromised. Back up your data and rebuild. If you cannot rebuild yet, remove SSH keys you do not recognise, including one tagged
@zeabur-pentest, change the root password and turn off SSH password login. - Check your bills from 14 October onward, and from 1 September for dedicated servers on Google Cloud.
- GitHub users: review your audit log for Zeabur GitHub App activity on 15 October between 15:05 and 18:54 UTC.
Then move off the platform. The shutdown notice by founder Yuanlin Lin, dated 17 October, says dedicated server renewals stop on 1 December and running shared cluster services are paused that day, and everything stops by 31 December. The data deletion date has not been set yet, and Zeabur advises not to wait for it before backing up. Domains can be transferred out from the Dashboard.
Moving off Zeabur
- Check each server's expiry date. Zeabur says servers shut down on their own expiry date during December, so that date, not 31 December, is your deadline.
- Back up your data and databases first, then move domains out through the Dashboard. Zeabur's shutdown notice points to a migration guide on its blog.
- Create new secrets on the new host. Do not copy the old values across. Zeabur asks users to replace every credential that was stored in its environment variables, so the old ones are no longer safe.
- Ask the next host the questions Zeabur's reports raise: do its access tokens expire and have scopes, does it keep access records, is its admin interface reachable from the public internet, and how are customers on shared infrastructure kept apart.
- Contact Zeabur Support early if your service is down, you cannot reach your data, or you see unusual activity. The shutdown notice asks users to contact Support early in those cases.
How to Fix It on Any Platform
Any platform where you set environment variables, from Vercel and Railway to a VPS, holds a copy of them. You cannot audit its security, but you can make a leak cheaper:
- Keep a list of every secret. When a platform you use is breached, the slow part is remembering what you stored there. A short table, like the example below, turns that into a checklist.
- Prefer keys that expire, and scope them. Zeabur's tokens never expired, and that is one reason they still worked for the attacker. Where your provider offers expiry or narrow permissions, use them.
- Do not put admin panels on the open internet if you can avoid it. Zeabur's cluster admin interface was publicly reachable.
- Scan your repositories for secrets, private ones too, and move what you find out of the code.
| Secret | Stored on | Where to revoke it | Expires? |
|---|---|---|---|
| Payment API key | Hosting env vars | Payment provider dashboard | Fill in |
| Database password | Hosting env vars and the database | The database itself | Fill in |
| AI API key | Hosting env vars, n8n | AI provider console | Fill in |
# GOOD: find secrets sitting in your files before someone else does
gitleaks dir .
A key you deleted can still sit in old commits. Our guide to secrets in git history shows how to scan the full history and remove what you find. If you host on Vercel, the Vercel environment variables guide covers which variables are safe to expose.
Tools like VibeDoctor's Vibe Check (vibedoctor.io) automatically scan your codebase with Gitleaks and their own secret checks, and flag cloud keys, tokens and passwords with specific file paths and line numbers. Free to sign up.
FAQ
I only used Zeabur's shared cluster. Am I affected?
Zeabur's report says environment variables and secrets for services in 9 regions were read, partly confirmed, and that commands ran inside 865 user database services. It asks all users to replace every credential in their environment variables, and shared cluster users to also change passwords inside their databases.
I rotated my keys after the August incident. Is that enough?
No. Zeabur's October report says to replace all credentials even if you rotated after August, because the October attack read the environment variables stored on the platform.
When does Zeabur shut down?
New dedicated server and domain purchases stopped on 17 October. On 1 December renewals are disabled and running shared cluster services are paused, and all servers and clusters stop by 31 December 2026. The data deletion date and final export deadline are still to be announced.
Why rotate in the order "revoke first, then redeploy"?
That is Zeabur's instruction. Until you revoke the old key with the provider, it keeps working for whoever copied it. Revoking first closes that door, and redeploying with the new key brings your app back.
Is a private GitHub repository a safe place for production keys?
Zeabur's own breach started with keys stored in plaintext in a private configuration repository. Private limits who should see the file. It does not protect the keys once any account, machine or tool with access is compromised.