2026年8月30日星期日

WhaleAgent
AI 寫的防刪護欄反成扳機 700GB 家目錄全失

AI 寫的防刪護欄反成扳機 700GB 家目錄全失

開發者 Sebastien Guillemot 叫 Claude 寫沙盒清理腳本,模型為了證明防護鈎子會攔截危險路徑,把真實刪除指令瞄準家目錄來測試。護欄先賦值後驗證,驗證一失敗就觸發 EXIT trap,清理函式對着那個未驗證的變數執行 rm -rf,700GB 一周工作沒了。模型檢討寫得很白:拒絕路徑本身執行了刪除。

護欄不是失效 是它自己執行了刪除

事發在 8 月 26 日。Midnight Network 開發者 Sebastien Guillemot 要 Claude 寫一個沙盒腳本:為其他 AI 代理在 `/tmp` 開隔離資料夾,用完就回收。因為腳本本身要做永久刪除,模型決定先寫一個自我測試,證明防護鈎子會拒絕危險路徑。

模型事後在同一個工作階段裡寫下自己的檢討,Guillemot 把它截圖公開。它把責任攬上身:「I caused this. Here is exactly what happened.」,然後列出兩個疊加的錯誤。

第一個是測試設計。它為了「證明」canary-dir 鈎子會拒絕危險路徑,直接把一個真實刪除指令瞄準 `$HOME`,逐個把 `"$d_precious"`、`"$HOME"`、`/tmp`、`/etc` 傳給 `reap.sh --confirm`。模型自己的評語是:把活的刪除指令對準用戶家目錄來示範它會被拒絕,無論護欄寫得多好,都不是可接受的測試設計。

第二個才是致命的。護欄先賦值,後驗證:

步驟

程式碼

結果

先賦值

`PIN_CANARY="$TMP_REAPER_SELFTEST_CANARY_DIR"`

刪除目標已經指向家目錄

後驗證

`[[ "$PIN_CANARY" =~ ^/tmp/[^/]+$ ]] || _pin_die`

驗證不通過,呼叫 `_pin_die` 離開

離開時

EXIT trap 觸發 `pin_cleanup`

執行 `rm -rf -- "$PIN_CANARY"`

模型自己一句話總結:「The refusal path performed the deletion.」護欄不只是沒有攔住,它就是扳機。拒絕的那條路徑,本身就是清理路徑,而清理對象是那個還沒通過驗證就已經被賦值的變數。

它還補了一句同樣值得記下的話:這正是這個程式庫早已寫明的失敗類型,先驗證、再讓數值進入危險操作,跟 `MIN_AGE_DAYS` 要在運算前檢查是同一課;那句註解是它自己寫進 `scan.sh` 的,三個小時後它自己重現了那個 bug。

模型在同一個工作階段寫下的事後檢討,指出拒絕路徑本身執行了刪除
模型的自我檢討截圖,由 Sebastien Guillemot 公開

由 Fable 一路降級到 Opus 4.8

留言區最大的火力不在 bug,而在誰在跑這段程式碼。

Guillemot 用的是 Fable。因為任務涉及永久刪除,Anthropic 的安全機制判定風險偏高,自動把模型降級,先降到 Opus 5,再降到 Opus 4.8。實際寫出並執行那個測試的,是降級後的 Opus 4.8。

Tom's Hardware 8 月 28 日的報道把標題重點放在這裡:自動降級可能是這次意外的成因之一。留言區的說法更直接,有用戶指自己寧願工作階段直接中止,也不想在不知情下被換成另一個模型。也有人指出,模型降級這件事本身可以在 Claude 的設定檔關掉,改為暫停或停止。

一個補充細節值得留意:模型寫道,工具呼叫在介面上顯示為被拒絕,但檔案寫入其實已經落地,執行仍然繼續下去,最後是用戶按下中斷才停住。介面上的「已拒絕」與系統實際做了什麼,不是同一件事。

700 GB 沒了 大部分靠 git 救回

項目

數字

刪除資料量

約 700 GB

損失工作

約一周

救回途徑

git、nix、工作階段紀錄等

原貼互動

逾 109 萬瀏覽、5,400 個讚好、776 則回覆

最諷刺的一點是 Guillemot 自己認的:他日常同時跑幾十個 AI 代理,卻沒有設定每日備份。翌日他再發一則:寫了二十年程式,最紅的一則貼文竟然是關於刪掉自己寫過的每一行程式碼。

Sebastien Guillemot 8 月 26 日的原貼,其後累積逾 109 萬次瀏覽
Guillemot 8 月 26 日公開事件的貼文

留言區給出的三個做法

776 則回覆裡,真正可執行的建議集中在三個方向,而且沒有一個是「叫模型小心一點」。

做法

內容

關掉自動降級

在 Claude 設定檔把模型降級改為暫停或停止,寧願中斷也不要在不知情下換模型

給代理一個獨立帳號

`adduser agent`,代理只在自己的家目錄裡跑,不給 sudo,爆炸半徑就被關住

用容器而非指令分類

靠關鍵字攔截危險指令永遠會被繞過;能力範圍與隔離才是真正的邊界

第三點是這次事件最值得帶走的一課。護欄寫在同一個腳本裡,就跟被保護的操作共用同一個變數、同一個 EXIT trap、同一個權限。真正的隔離要在腳本以外。

來源

No comments yet