Zeabur 環境變數外洩:官方教你放 API Key 的地方,就是被讀走的地方
Zeabur 8 月 28 日公告:一組內部服務憑證被未授權使用,讀走了部分專案的環境變數紀錄。官方列出 26 個確認外洩的變數名,ANTHROPIC_API_KEY、OPENAI_API_KEY、AWS_SECRET_ACCESS_KEY、GITHUB_TOKEN、DATABASE_URL 都在名單上,值符合 AWS、GitHub、Anthropic、OpenRouter、OpenAI、Stripe 憑證格式的自訂變數名也一併確認。同日 17:42 的更新提到 LiteLLM 的可疑活動正在調查是否相關,AI Hub 服務暫時停止。受影響人數、攻擊發生日、憑證怎麼流出,官方沒說。
事實分級:事件經過、變數名單、建議動作來自 Zeabur 8 月 28 日的狀態頁公告(含同日更新);AI Hub、環境變數、安全實踐的描述來自 Zeabur 官方文件(分別更新於 2026 年 3 月 26 日、3 月 19 日、5 月 15 日);LiteLLM 3 月事件來自 LiteLLM 與 PyPI 官方部落格;Vercel 4 月事件來自 Vercel 官方公告;Anthropic 金鑰管理來自 Anthropic 官方文件。受影響人數、攻擊發生日、憑證流出方式,官方公告沒有說。
Zeabur 的 AI Hub 文件裡,安全性最佳實踐列了四條,第二條寫著:「使用環境變數:將 API 金鑰儲存在環境變數中」。8 月 28 日,Zeabur 在狀態頁公告,一組內部服務憑證被未授權使用,讀走了部分專案的環境變數紀錄。
照著文件做的人,把金鑰從程式碼裡搬進了環境變數。被讀走的那一份紀錄,裝的就是搬進去的東西。
官方在同一份公告裡列出 26 個確認外洩的變數名,要求受影響用戶立刻撤銷並更換,同日稍晚又暫時停止了 AI Hub 服務。受影響人數、攻擊發生日、內部憑證怎麼流出,公告從頭到尾沒說。三件事都在 8 月 28 日這一天公告。
Zeabur 8 月 28 日公告:一組內部服務憑證被未授權使用,26 個變數名確認外洩
事件頁的標題是 Unauthorized Access to Project Environment Variable Data,建立時間 8 月 28 日 07:11 UTC,換算台北時間是當天下午 3 點 11 分。狀態標成 Degraded,受影響服務只寫了一項:儀表板的專案頁面。公告本文的說法是,偵測到一組「internal service credential」被未授權使用,用途是取得專案的環境變數紀錄;官方寫「contained the incident on the same day」,同一天撤銷了那組憑證、封鎖了存取路徑。
確認外洩的 26 個變數名,官方是一個一個列出來的。一眼掃過去,範圍從 AI 服務金鑰、雲端主控台憑證、程式碼託管 token,一路蓋到資料庫連線字串。照用途分成三組看比較快:
- AI 服務金鑰(5 個):
ANTHROPIC_API_KEY、OPENAI_API_KEY、OPENROUTER_API_KEY、GEMINI_API_KEY、GOOGLE_API_KEY - 雲端、程式碼託管與金流(10 個):
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、CF_API_TOKEN、CLOUDFLARE_API_TOKEN、DIGITALOCEAN_TOKEN、LINODE_TOKEN、GITHUB_PAT、GITHUB_TOKEN、STRIPE_SECRET_KEY、STRIPE_PUBLISHABLE_KEY - 資料庫與應用密鑰(11 個):
DATABASE_URL、MONGODB_URI、MYSQL_PASSWORD、POSTGRES_PASSWORD、REDIS_PASSWORD、JWT_SECRET、SECRET_KEY、API_SECRET、ACCESS_TOKEN、CLIENT_SECRET、PRIVATE_KEY
名單之外還有一句更重要的:值符合 AWS、GitHub、Anthropic、OpenRouter、OpenAI、Stripe 憑證格式的自訂變數名,官方一樣確認外洩。把 OPENAI_API_KEY 改名叫 MY_LLM 擋不住這一輪,認出來的是值的長相,不是欄位名。清點要看兩層:26 個名稱,加上值符合那六家格式的自訂名稱。
受影響用戶會收到直接通知,內容包含哪個專案、哪個服務、哪個環境,以及建議的輪替動作。官方用 strongly recommend 的字眼,要求立即撤銷並更換所有列出的憑證,同時檢查對應的資料庫與第三方服務有沒有異常存取、異常用量、異常費用。
帳號那一側,公告寫的是截至當下沒有找到證據:Zeabur 帳號憑證、個人資料、伺服器資料、付款與信用卡資料都沒有被存取的跡象,調查仍在進行。這句話的時態鎖在 8 月 28 日,往後幾天的結論要看官方後續更新。
受影響人數、攻擊發生日、憑證怎麼流出、金鑰有沒有被用過,公告四件都沒說
受影響的用戶與專案有多少,沒說。攻擊實際發生在哪一天,沒說。那組內部憑證是怎麼被拿到的,沒說。已經外洩的金鑰有沒有被人實際使用過,也沒說。
四個空格不必自己填。
公告時間 8 月 28 日 07:11 UTC 是官方發文的時刻,不是事件發生的時刻。兩者相差多久,公告沒有交代,所以輪替的時間窗只能往前抓得保守一點,不能從 8 月 28 日起算。
能查到最接近規模的數字是 2025 年 11 月的天使輪公告,Zeabur 自述當時有超過 5000 位個人付費客戶,同一篇也寫年底要在台北市啟用第一個辦公室。九個多月前的付費客戶數,跟這次的受影響範圍是兩件事,不能拿來當分母。
| 問題 | 官方公告 |
|---|---|
| 發生什麼事 | 一組內部服務憑證被未授權使用,用來取得專案的環境變數紀錄;同日撤銷憑證、封鎖存取路徑 |
| 哪些變數 | 確認外洩 26 個變數名;值符合 AWS、GitHub、Anthropic、OpenRouter、OpenAI、Stripe 憑證格式的自訂變數名也在內 |
| 誰會被通知 | 受影響用戶收到直接通知,含專案、服務、環境與建議輪替動作 |
| 帳號與付款資料 | 截至公告當下無證據顯示帳號憑證、個人資料、伺服器資料、付款與信用卡資料被存取;調查持續中 |
| 受影響人數 | 沒說 |
| 攻擊發生日 | 沒說 |
| 憑證怎麼流出 | 沒說 |
| 金鑰是否已被使用 | 沒說 |
8 月 28 日 17:42 的更新提到 LiteLLM 的可疑活動,AI Hub 服務暫時停止
同一天 17:42 UTC,狀態頁多了一則更新:發現與 LiteLLM 有關的可疑活動,LiteLLM 是 Zeabur AI Hub 這項服務在用的元件。官方原句是「investigating whether this activity is related to the incident」,接著宣布調查期間暫時停止 AI Hub 服務。暫停的是整項服務,兩件事寫在同一則更新裡。
AI Hub 是 Zeabur 的統一 AI 服務平台,文件最後更新在 2026 年 3 月 26 日:一把 API 金鑰存取 OpenAI、Anthropic Claude 等多家的模型,點數預付制,端點放在東京 hnd1 與舊金山 sfo1,介面相容 OpenAI API 格式。一把金鑰打通多家供應商,方便在這裡;這把金鑰本身有沒有波及,官方沒說。
LiteLLM 今年 3 月出過一次供應鏈事件。LiteLLM 3 月 24 日的官方安全公告寫,v1.82.7 與 v1.82.8 兩個版本遭植入憑證竊取程式,會蒐集環境變數、SSH 金鑰、雲端憑證、Kubernetes token 與資料庫密碼,外傳到與 LiteLLM 無關的網域;建議動作是輪替所有 secret;LiteLLM 自己的判斷是,起點在 CI 裡的一個 Trivy 相依。PyPI 4 月 2 日的事件報告給了另一個尺度:惡意版本從上架到下架 2 小時 32 分,這段期間下載超過 119,000 次,數字是 PyPI 自報。
兩個多小時,十一萬次。
官方在查的是 8 月 28 日發現的那個可疑活動與本案是否相關,沒有把它指成 3 月那件事。3 月的供應鏈事件與 8 月 28 日的環境變數外洩,目前能並排的是時間與一個元件名稱,不是因果關係。查的結果什麼時候出來、會不會公布,公告也沒說。
環境變數解決的是「別進 git」,不是「別被平台讀」
AI Hub 文件的安全性最佳實踐四條,照抄如下:「妥善保管 API 金鑰:不要將 API 金鑰提交到版本控制系統」「使用環境變數:將 API 金鑰儲存在環境變數中」「定期輪換:定期撤銷舊的 API 金鑰並建立新的」「監控使用量:定期檢查使用歷史,留意異常的 API 呼叫」。
四條沒有一條是錯的,環境變數本來就是業界常規。我把這次事件讀成一次守備範圍的誤會:前兩條防的是金鑰被提交進版本控制、跟著程式碼公開出去,防不到平台內部那條讀得到紀錄的路徑。
Zeabur 的環境變數怎麼設,文件寫得很清楚:在服務頁面的環境變數區新增,平台會自動注入服務主機、連接埠與資料庫連線這幾類變數,也支援用 .env 格式一次大量編輯,還能用 ${VAR} 互相引用。整份文件的重心放在怎麼設得方便。
文件沒有寫的是另一半。整份環境變數文件裡,找不到加密、敏感、隱藏、遮蔽這幾個詞,也沒有把某個變數標記成敏感的功能說明。存進去之後有沒有另外一層保護,文件上是空白。
安全實踐頁(最後更新 2026 年 5 月 15 日)談的是另一個層次:SOC 2 Type II 申請中;正式環境資料存放在 MongoDB Atlas,預設 AES-256 靜態加密;正式資料庫只接受 Tailscale 連線的裝置;員工 Google Workspace 強制兩階段驗證;最小權限、存取定期審查;有文件化的事件回應計畫。
靜態加密守的是靜置在儲存層的資料。我的讀法是:一組本來就有權讀取紀錄的憑證,走的不是那一層,加密未必擋得到它。公告沒有描述那份紀錄被取出時經過哪些環節,只寫了憑證被撤銷、存取路徑被封鎖。
另一宗也涉及環境變數的事件 4 月出現過,主角是 Vercel,也是 Zeabur 創辦人自述最早那個 MVP 對標的名字(「後端版的 Vercel」)。Vercel 4 月 19 日到 24 日之間更新的公告寫,攻擊者可以列舉並解密非 sensitive 的環境變數,括號註明是「those that decrypt to plaintext」;受影響範圍寫的是有限的一部分客戶,加上少數額外帳號。
Vercel 給的建議動作有四項:輪替沒有標記成 sensitive 的變數、改用 sensitive environment variables 這項功能、檢查活動紀錄、把 Deployment Protection 至少開到 Standard。四項都是用戶自己動手;其中改用 sensitive environment variables 這一項,前提是 Vercel 有那個開關。Zeabur 的環境變數文件沒有寫有沒有對應的開關。
Zeabur 自己有一項功能剛好落在第一條的守備範圍:安全報告會用 AI 掃描程式碼,檢查項目包含 Secret Key 和敏感資訊外洩,這份文件更新在 2026 年 3 月 18 日。文件寫的是分析使用者的程式碼;平台自己那一側有沒有被掃,文件沒寫。
今天要做的四件事:逐把撤銷、查用量與帳單、清點自訂變數名、設金鑰到期日
官方的立即輪替建議是對已通知者說的;沒收到通知的人要不要動,公告沒說。我的建議是動:名單上的變數名出現在自己的 Zeabur 專案裡,就照下面四件事做。順序有差。
- 逐把撤銷、重建:新建一把金鑰不會讓舊的失效,每個平台的每把金鑰各自獨立,得一把一把處理。
- 查用量與帳單:官方建議的動作裡包含檢查對應的資料庫與第三方服務有沒有異常存取、異常用量、異常費用。
- 把自訂變數名也算進去:官方確認值符合 AWS、GitHub、Anthropic、OpenRouter、OpenAI、Stripe 格式的自訂名稱同樣外洩,改過名字的變數要一起清點。
- Anthropic 這一側可以做得更細:組織帳號有 Admin API,能列出狀態為 active 的金鑰、把單一金鑰的狀態改成 inactive;每一把金鑰另外有到期日欄位。個人帳號沒有 Admin API,要到 Claude Console 手動處理。其他平台的撤銷動作在各自後台。
四件事裡最容易漏的是第三件。改名擋不住官方已經認得的六家憑證格式,8 月 28 日的公告把這一點寫明了。清點的是 26 個名稱,加上值符合那六家格式的自訂名稱——要找出後者,得把整份環境變數的值看一遍。
金鑰到期日則是另一種思路。輪替之所以難落實,是因為它靠人記得;Anthropic 每一把金鑰都有到期日欄位,建立的時候順手設一個,輪替就不只靠人記得。
把自己 33 個 repo 掃過一次,134 筆命中沒有一筆是真密鑰
同一天把自己的專案也掃了一遍。同一個 GitHub 帳號底下 33 個 repo,8 個公開、25 個私有;掃描範圍是 8 個公開 repo 的全部歷史、21 個私有 repo 的全部歷史、1 個靜態部署目錄,以及 9 個已部署站台的首頁與前端 JS。工具是 gitleaks 8.30.1,輸出全程遮蔽。
公開 repo 命中 134 筆,逐筆核對之後,真密鑰 0 筆。129 筆是同一把 Firebase Web SDK 的前端 apiKey 在不同 build 檔裡重複出現——Firebase 的設計本來就讓這把 key 隨 client 公開,真正的鎖在 Security Rules,這次沒查。1 筆是 IndexNow 的站權金鑰,規範本來就要求公開放在站根。剩下 4 筆是頁面內容的 SHA-256 指紋,檔名就叫 page-fingerprints。
私有 repo 命中 8 筆,同樣 0 筆真密鑰:綠界官方公開的測試環境憑證、單元測試用的假金鑰字串、IndexNow 金鑰,以及另一把 Firebase 前端 apiKey,真正的鎖一樣在 Security Rules,這次沒查。八筆分屬四種類型,沒有一種是連線正式服務用的憑證。
已部署站台那一側,前端 JS 用嚴格版的規則掃 sk-ant-、sk-proj-、AIza、ghp_、AKIA 這些前綴,0 命中。一個站的 HTML 命中 sk-ant- 字樣,核對之後是「自帶 API Key」輸入框的 placeholder。這一輪看的是 9 個站的首頁和抓得到的前端 JS,掃的是打包後送到瀏覽器的檔案。
0 筆真密鑰不等於防護到位。8 個公開 repo 裡,2 個完全沒有 .gitignore,5 個有 .gitignore 但沒排除 .env*、*.key、credentials* 這類檔名,只有 1 個排除了。乾淨的結果來自沒有把金鑰寫進檔案,不是來自有東西擋著。
沒炸是運氣,不是防護。
另外一筆值得記下來:本機有一個檔名就叫 api.key 的檔案,躺在 repo 目錄的上一層,不在任何 git 追蹤範圍,沒被推上去過。gitleaks 掃的是 git 歷史,這個檔從來沒進過歷史,掃描結果裡自然也不會有它。位置差一層,結果差很多。
給非工程師的一句話
回到 AI Hub 那份文件。它教的是把 API 金鑰從程式碼裡搬出來、放進環境變數,這件事今天仍然要做;8 月 28 日公告的是另一件事——搬進去之後,平台內部有一條讀得到那份紀錄的路徑,而那條路徑被人用了。名單上有 26 個變數名,ANTHROPIC_API_KEY、OPENAI_API_KEY、DATABASE_URL 都在;受影響人數、攻擊發生日、憑證怎麼流出、金鑰有沒有被用過,公告都沒說。這篇的建議是:逐把撤銷重建、查用量與帳單、把值符合六家格式的自訂變數一起清點;Anthropic 的金鑰可以順手設一個到期日。
常見問題
Zeabur 這次外洩了什麼?
官方公告寫的是部分專案的環境變數紀錄。確認外洩的變數名有 26 個,涵蓋 AI 服務金鑰(ANTHROPIC_API_KEY、OPENAI_API_KEY、OPENROUTER_API_KEY、GEMINI_API_KEY、GOOGLE_API_KEY)、雲端與程式碼託管憑證(AWS、Cloudflare、DigitalOcean、Linode、GitHub、Stripe),以及資料庫與應用密鑰(DATABASE_URL、MONGODB_URI、各種密碼與 SECRET_KEY)。值符合 AWS、GitHub、Anthropic、OpenRouter、OpenAI、Stripe 憑證格式的自訂變數名,官方也一併確認。截至公告當下,官方說沒有找到 Zeabur 帳號憑證、個人資料、伺服器資料與付款資料被存取的證據。
沒有收到通知,還需要換 key 嗎?
官方說受影響用戶會收到直接通知,內容包含專案、服務、環境與建議的輪替動作。沒收到通知的人要不要動,公告沒有說,官方也沒有公布受影響的用戶與專案數量。我的建議是動:名單上的變數名出現在自己的 Zeabur 專案裡,就撤銷重建;輪替有作業成本,這是要自己衡量的。同時檢查對應的資料庫與第三方服務有沒有異常存取、異常用量、異常費用,這是官方對已通知者的建議之一。
LiteLLM 是這次外洩的原因嗎?
官方沒有這樣說。8 月 28 日 17:42 的更新只寫了兩件事:發現與 LiteLLM 有關的可疑活動,LiteLLM 是 Zeabur AI Hub 這項服務在用的元件;以及調查期間暫停 AI Hub 服務。官方對兩者關係用的動詞是在調查是否相關。LiteLLM 今年 3 月出過一次供應鏈事件,兩個版本遭植入憑證竊取程式,那是今年 3 月的另一次事件;官方這次在查的是 8 月 28 日發現的 LiteLLM 可疑活動與本案是否相關,沒有說那就是 3 月那件事。
Anthropic 的 API key 怎麼撤銷?
組織帳號可以用 Admin API:列出狀態為 active 的金鑰,把單一金鑰的狀態更新為 inactive。每一把金鑰另外有到期日欄位,可以在建立時就設好期限,不必等出事才想到輪替。個人帳號沒有 Admin API,要到 Claude Console 手動處理。要注意的是,新建一把金鑰不會讓舊的失效,每個平台的每把金鑰各自獨立,得一把一把撤銷。其他平台的撤銷動作在各自後台。
📚 收進你的工具
For AI Reading Era把這篇文章交給你日常用的工具——做研究、整理筆記,或當 AI 的 context。