跳至內容

PaaS 的方便,是用信任換來的:從 Zeabur 資安事件反思開發者基本功

2026 年 8 月底,台灣起家的雲端部署平台 Zeabur 發生了 Environment variable 外洩事件,攻擊者取得內部管理憑證進入資料庫,鎖定並匯出使用者的 AI API 金鑰與各類敏感憑證。

雖然收到通知信的那一刻,我手邊在 Zeabur 上的實驗專案其實早就停用了。當初有幾個自己的小實驗專案圖方便把服務丟上去跑,停用時早已順手把金鑰撤銷,因此這次沒有受到實質損失。

但這封信依然提醒了一件事:我們享受平台帶來的一鍵部署時,也在不知不覺中把系統的信任邊界交託了出去。

別誤會了,雖然這次事件在社群上引發了不少討論,但我並不是要在這裡一起鞭 Zeabur 畢竟在脆上鞭打的人很多也不差我一個,而是想藉由這次事件,從開發者的角度談談在 PaaS 與 AI coding 時代,不管你是不是 vibe coder,那些仍然無法卸掉的資安與維運責任。


先從這次事件看起

雖然各種謠言與臆測在社群上滿天飛,無論事實是不是如同官方所說,但根據官方狀態頁(incident #1037896)目前公布的調查結果,攻擊者取得了一組外洩的 Zeabur 內部 AWS 管理憑證,進入東京區域的叢集,接著透過 VPN 取得控制平面網路(Control Plane Network)的存取權限,最後連入主要資料庫。

Zeabur 事件攻擊鏈示意圖:外洩的 Zeabur 內部 AWS 管理憑證是初始入侵點,攻擊者進入東京區域叢集,透過 VPN 取得控制平面網路存取,連入主要資料庫,最後定向匯出使用者環境變數中的 AI 金鑰、連線字串與各類 Token

進入資料庫之後,攻擊者針對使用者設定的環境變數進行定向查詢與匯出,專門鎖定 OpenAI、Anthropic、OpenRouter 等 AI 服務的金鑰,以及資料庫連線字串與各種存取權杖(Token)。官方也證實,已有部分使用者的 Anthropic 與 OpenAI 金鑰遭到實際盜用盜刷。

我收到的通知信,是官方在進一步清查後發出的第二批通知:

Zeabur 寄來的安全事件更新通知信,標題為「請輪替新增確認受影響的環境變數」,內文列出 ANTHROPIC_API_KEY、OPENAI_API_KEY、DATABASE_URL 等受影響的環境變數名稱

信中列出的受影響項目包含 ANTHROPIC_API_KEYOPENAI_API_KEYOPENROUTER_API_KEYDATABASE_URLGITHUB_TOKENJWT_SECRET 以及各類資料庫密碼,範圍相當廣泛。

但有一點要先說明:Zeabur 官方目前正在委託第三方資安團隊進行鑑識,完整的根因分析尚未出爐。 官方先前因偵測到 LiteLLM 的可疑活動而主動停用 AI Hub 服務,截至寫這篇時(2026/08/30),官方表示兩者是否有關仍在調查中,尚未給出定論。 是說比起這個我更關心我之前在 AI Hub 裡面儲值的 Token 能不能退費...

PaaS 沒有消除複雜度,只是替你承擔複雜度

很多人選擇平台即服務(PaaS, Platform as a Service),是因為它把伺服器建置、網路路由、容器封裝與環境變數注入簡化成一個按鈕。你把程式碼推上 Git、把金鑰貼進後台,幾秒鐘後服務就順利上線了。

這種極致的流暢感容易讓人產生錯覺,以為基礎設施的複雜度消失了。

其實底層的複雜度從來沒有消失。身分與存取管理(IAM)、內部網路隔離、控制平面安全、資料庫存取審計與金鑰儲存機制,這些工作依然存在,只是從你自己的雲端帳號搬進了平台的內部架構裡。

當你把金鑰交給平台,平台就成了你系統信任邊界(Security Boundary)的一部分。平台內部任何一個環節出現破口,你的機密資料就會跟著暴露。

信任邊界示意圖:把金鑰貼進 PaaS 後台後,真正的信任邊界從你的專案擴張到整個平台內部(管理介面、內部憑證、控制平面、中央資料庫),平台內部任一環節被攻破,存放在資料庫裡的金鑰就跟著暴露

選擇 PaaS 本質上是一筆信任交易。我們用託管換取開發速度,但同時也必須認清:只要資料躺在別人能解密讀取的地方,對方的安全體質就直接決定了你的安全上限。

Environment variable 與 Secret Manager 的差別

事件發生後,很多人開始疑惑:既然環境變數會被整批撈走,難道我們一開始就不該把 API 金鑰放進環境變數嗎?

這要回到軟體開發的演進來看。過去大家常把連線字串與金鑰直接寫在程式碼裡,一不小心推上 Git 就等於昭告天下。為了解決這個問題,業界推崇的 Twelve-Factor App 原則提出把設定與程式碼分離,透過環境變數(Environment Variables)在啟動時注入應用程式。Zeabur 官方文件也是這樣建議,這確實是極為常見且標準的做法。

但初學者容易忽略的一件事是:環境變數只是一種傳遞設定的管道,它本身並不是一套完整的機密管理(Secrets Management)系統。

環境變數說穿了,就是在程式啟動(行程,Process)的時候塞進去的一串純文字設定。它會外洩,其實有兩種完全不一樣的情況。

一種是「跑起來以後」漏的,屬於執行期(Runtime):伺服器把記憶體整個倒出來(記憶體傾印,Memory Dump)、程式出錯把訊息印進日誌(錯誤日誌,Crash Log)、或不小心開了沒鎖好的除錯後門,值就被看到了。另一種是「存放的地方」被端走,屬於儲存層(Storage):設定被集中塞在某個資料庫,那個庫整個被搬空,值就一次全曝光。

這次 Zeabur 是後面那種。把金鑰放進環境變數這個動作,本身沒有直接引爆這次外洩。真正被打爆的,是平台幫大家集中保管設定的那個資料庫。但這也剛好戳破一個常見的誤會:環境變數只管把設定「送進來」,至於送進來之前存在哪、有沒有加密、誰摸過它,它通通不管。

為了因應更高的安全性要求,業界才發展出機密管理服務(Secret Manager),例如 AWS Secrets Manager、Google Cloud Secret Manager 或是 HashiCorp Vault。這類專門系統提供靜態與傳輸加密、嚴格的存取稽核紀錄(Audit Log),並支援自動化輪替(Rotation)與動態短期憑證。

這些機制真正有用的地方,是在「資料庫整個被端走」的時候,把災情壓到最小。動態短期憑證的意思是,攻擊者就算撈到東西,拿到的也是很快就過期的臨時通行證,而不是那把能一直用下去的永久金鑰;上鎖的鑰匙又擺在另一個地方,光把資料庫搬走也打不開;稽核紀錄則讓你事後至少查得到,是誰、在什麼時候動過。當然這不是萬靈丹,萬一平台連機密管理服務的最高權限都被摸走,一樣可能被整批倒出來,只是災情比較收得住,也留得下線索。

這兩者的差異,本質上是安全成熟度與維運成本的取捨:

  1. 直接寫死在程式碼裡。 風險極高,一旦進入版本控制就可能永久留痕,應該絕對避免。
  2. 交給託管平台的環境變數。 適合個人專案與中小型服務,能有效避免金鑰進 Git,但同時也把這份機密的保護責任交給了平台的資料庫與管理介面。
  3. 導入專門的機密管理服務。 適合正式生產環境與敏感系統,透過身分驗證與短期權杖降低外洩衝擊,但需要付出相對應的架構與維運成本。

其實這三層中間還有一塊灰色地帶。像 Doppler、Infisical 這類工具(業界叫 SecretOps),能讓你不用自己扛一套 Vault,就把金鑰集中管好、再自動塞進各個平台,對小團隊來說算是花小錢辦大事。寫這篇的時候,它們大多都接得上主流的 PaaS,值得花點時間試試。

明白這層區別,就能更清楚看見自己所處的安全層級,不再誤把環境變數當成無懈可擊的防護罩。

環境變數與 Secret Manager 對比圖:左側環境變數是行程啟動時注入的純文字值,暴露面分兩種,執行期漏包含記憶體傾印、錯誤日誌與不安全的除錯端點,儲存層漏則是中央資料庫被拖走(即這次 Zeabur 事件),適合個人與中小型專案;右側 Secret Manager 是加密保險庫,應用程式先身分驗證再取得會過期的短期權杖,提供靜態與傳輸加密、存取稽核、自動輪替與動態短期憑證,適合正式生產與敏感系統;底部光譜顯示寫死程式碼、環境變數、Secret Manager 三種存法的安全成熟度與維運成本由低到高

這次初始入侵點在平台端,但開發者依然能控制自己的爆炸半徑

事件在社群發酵時,有人急著下結論:「這證明了 vibe coding 寫出來的東西就是危險。」把責任全推給 vibe coding 是把問題看扁了。

這次的初始入侵點(Initial Compromise)發生在雲端平台自身的內部管理憑證。 就算專案是由資深架構師一行行純手寫、架構極其嚴謹,只要部署在同一個環境並將金鑰存於平台,在同樣的攻擊路徑下依然會被讀取。

當攻擊者一連進資料庫,就能把所有人的金鑰「明著」整批複製走。這代表這些機密躺在資料庫裡的時候,很可能根本沒再替它們上一層鎖,也就是所謂的應用層加密(Application-Level Encryption);又或者負責加解密的那把總鑰匙,也就是金鑰管理服務(KMS),跟資料庫放在同一個保險箱裡,拿到一個等於拿到全部。而一組管理憑證外洩就能撈遍每一位使用者,也代表使用者彼此之間的隔離,也就是租戶隔離(Tenant Isolation),其實沒真的擋住。

這些都是 Zeabur 平台該扛的責任,不能算到使用者頭上。

但真正值得思考的是後續的差異:為什麼在同一起外洩事件中,有些專案的金鑰被盜刷了幾千美元、資料庫被翻盤,有些人卻能全身而退?

關鍵在於開發者有沒有主動控制自己的爆炸半徑(Blast Radius)。

Blast Radius 指的是單一元件遭到攻破時,損害可能擴散的最大範圍。就算平台的防線被突破,我們依然有幾道防護可以把損失限制在最小:

  1. 設定額度上限與警報機制。 為 OpenAI 或 Anthropic 金鑰設定每月用量上限(Usage Limit)與即時警報。就算金鑰外洩,攻擊者能刷的金額也立刻見頂,不至於收到天文數字帳單。
  2. 落實最小權限原則。 別隨手抓一把權限開到最大的 Admin Token 就拿去當一般應用程式的金鑰;資料庫連線也一樣,能只給讀就別給寫,照功能拆開。現在 OpenAI、Anthropic 也都能開專案層級(Project)的獨立金鑰了,有些還能限定只能用哪些模型、只能從哪個 IP 連進來,善用這些會比從頭到尾只用一把 master key 安全很多。
  3. 隔離不同環境的憑證。 測試環境與正式環境絕不共用同一組金鑰與資料庫,避免小實驗出事直接波及核心業務。
  4. 主動撤銷不再使用的金鑰。 專案停用或刪除後,要主動撤銷(Revoke)關聯金鑰。單純在後台建立新金鑰並不會讓舊金鑰失效,必須手動將舊金鑰撤銷,才能真正切斷風險。

AI 降低的是實作門檻,不是維運責任

AI 工具與 vibe coding 的普及,大幅降低了把想法變成可運作軟體的實作門檻。沒有深厚工程背景的人也能在幾小時內做出產品,這是非常棒的進步。

而在這樣的前提下,像 Zeabur 這樣的 PaaS 服務,自然就成了不少 Vibe Coder 的入門首選。教學跑到最後那步「來,把它部署上去」,示範用的常常就是這類平台,於是這波被掃到的人裡,有很多正是照著教學一步步做、跟著把金鑰貼上去的新手。課程通常把「怎麼做出來」教得很細,卻很少教「做出來之後怎麼顧」,這鍋,多少也得算它一份。

然而,軟體開發的實作門檻被壓低了,上線後的維運責任卻一分都沒有減少。

這一點不只寫程式的人這樣看。聯合報名人堂 2026 年 8 月的〈當 AI Agent 闖禍 誰去坐牢?〉裡,詹文男從企業管理的角度也提到,把 AI Agent 當同事看待,就得像管理員工一樣給它身分、職務與清楚的權限,而且:

責任不會因為決策者換成 AI Agent 而憑空消失,它只會沿著權力鏈條,落到最接近人類的那一端。

換句話說,無論中間隔了幾層 AI 或平台,鏈條末端總還是站著一個得負責的人。用白話來說,就是出事了,背鍋的還是人。

只要服務連上公開網路、開始存取真實世界的使用者資料與收費 API,身為產品擁有者,你就必須面對網路安全、權限控制與事故應變的現實。

這並非第一次技術演進帶來類似的挑戰。過去從組合語言邁向高階語言、從自建機房邁向雲端託管,每一層抽象化的出現都讓開發變得更容易。但抽象層往上疊,底層的運作規則從未消失;一旦底層晃動,能把系統穩住的依舊是對這些基本原理的理解。

我們不需要每個人都回去手刻每一行基礎架構,但至少要清楚自己的應用程式依賴了哪些外部服務、金鑰交給了誰,以及最壞情況發生時該如何止血。

那現在該做什麼?

如果你在 Zeabur 或其他 PaaS 平台上有部署專案,或者單純想為手邊的服務做一次健康檢查,有幾個具體的動作可以立刻執行:

  1. 手動撤銷(Revoke)受影響的舊金鑰。 這是這次事件中最重要的一步。很多開發者在收到通知後只到 AI 服務商後台按下「新建金鑰」,卻忘了單純建立新 Key 並不會讓舊 Key 自動失效。你必須手動將舊的 Key 執行撤銷(Revoke),才能徹底斷絕被盜刷的可能。
  2. 全面輪替資料庫密碼與第三方權杖。 包含 PostgreSQL、MySQL、Redis 的連線密碼,以及 GitHub 個人存取權杖(Personal Access Token)、Stripe 金鑰等。修改密碼後記得同步更新服務設定並重啟。
  3. 清查用量紀錄與設定費用警報。 登入各 AI 服務的後台儀表板,檢查過去幾天是否有異常的 Token 消耗或非預期的 API 呼叫。同時務必設定硬性用量上限(Hard Limit)與電子郵件警報,防止未來任何非預期的超額扣款。
  4. 徹底清理已廢棄或暫停的專案。 很多人以為在平台上把服務「暫停(Pause)」就沒事了,但躺在平台資料庫裡的環境變數依然完好無損。對於已經不再維護的實驗專案,除了在平台端徹底刪除,更要把專案所關聯的所有外部憑證全部註銷。
  5. 把資安基本觀念補齊。 趁著這次事件,花點時間搞懂什麼是最小權限、什麼是金鑰輪替、環境變數在不同平台如何儲存。遇到資安事件時,看得懂公告、知道該撤銷什麼,這份判斷力正是無法被 AI 代勞的基本功。

至於接下來要不要從 Zeabur 轉移到其他平台,這就要看你對 Zeabur 平台的信任程度與自身的風險承受度了。


PaaS 讓我們不必每天親自處理底層,但底層並沒有因此消失。這是一筆值得做的交易,只是交易的貨幣除了錢,還包括信任。

AI coding 也是一樣。它讓「做出來」變得前所未有地便宜,但只要那個東西真的上線,權限、資料、成本與事故的責任就不會跟著被抽象掉。

工具可以替你承擔複雜度,但不能替你承擔後果。

💬 留言討論