container-use:最新 release 是 v0.4.2,main 多了 27 個 commit,路徑穿越的問題與它的修補都沒進過任何 release
2026 年 8 月 12 日(UTC),container-use 的 issue #337 被關掉了。這張單從 3 月 18 日開著,標題是 exportEnvironmentFile 可以把檔案寫到 worktree 外面。關單時間是 16:30:36(UTC),一秒前,修補它的 PR #365 才剛合併。
照慣例這是好結局:有人回報,有人修,單子關了。我在 2026 年 11 月 6 日去查,releases/latest 還是 v0.4.2,發布日 2025-08-19。修補合併到今天過了 86 天,沒有任何一個 release 帶著它。
更怪的在另一頭。我讀了 v0.4.2 的 repository/git.go,那個被回報的函式根本不在裡面。
站牌停在 2025 年 8 月 19 日
container-use 在 dagger 組織底下,README 的說法是 “Each agent gets a fresh container in its own git branch”。意思是讓 Claude Code、Cursor 這類 agent 各開自己的容器和 git branch 做事,彼此不衝突,做壞了整個丟掉。接法是一行 claude mcp add container-use -- container-use stdio。
這個 repo 2025-05-23 建立,6 月 10 日出第一個 release v0.0.0,到 8 月 19 日的 v0.4.2 一共 14 個,約十週,沒有一個標 prerelease。之後就沒有了。2026-11-06 我查的時候,v0.4.2 發布已經 444 天。
先講我讀過什麼:gh api 的輸出、issue 和 PR 的原文、v0.4.2 與 main 的 repository/git.go,以及 install.sh。我沒有安裝它,沒有跑 install.sh,也沒有執行 issue 裡的重現步驟。下面凡是「會怎樣」的句子,都是讀程式碼推出來的。
README 給的安裝法是 curl -fsSL …/install.sh | bash。install.sh 第 107 到 109 行去打 releases/latest 抓 tag_name。照這個寫法,今天跑它會裝到 v0.4.2。
把 release 想成鐵路的站牌,install.sh 只會帶你到最後一個站牌。站牌後面的軌道其實有鋪,main 一路往前,只是那一段你搭不到車。
container-use 的兩條線(日期以 GitHub 紀錄為準,查詢日 2026-11-06)
2025-06-10
第一個 release v0.0.0。
2025-08-19
v0.4.2 發布,這是第 14 個,也是到今天為止的最後一個。
2025-08-26
commit a10f338(#285)引入 exportEnvironmentFile,比 v0.4.2 晚 7 天。
2026-03-18
issue #337 開出來,回報這個函式可以寫到 worktree 外。
2026-05-05
issue 裡有一位留言者寫道,自己已經不是 maintainer。
2026-08-11
PR #360 合併,標題是 “sync maintenance fixes from fork”。
2026-08-12
PR #365 在 16:30:35 合併,issue #337 在 16:30:36 關閉。
2026-11-06
releases/latest 仍是 v0.4.2,main 領先 27 個 commit。
七天後長出來的函式
exportEnvironmentFile 是 commit a10f338 加進來的,訊息是 “export 1 file at a time for edits and writes (#285)”,日期 2025-08-26。patch 裡有一行 absoluteFilePath := filepath.Join(worktreePath, filePath),往下沒有任何邊界檢查。
v0.4.2 發布在 8 月 19 日,早它 7 天。我用 contents API 讀 v0.4.2 的 repository/git.go,exportEnvironmentFile 出現 0 次。
我一開始不信。v0.4.2 的 git.go 裡 grep filepath.Rel 命中一筆,我以為那就是邊界檢查,也就是說舊版早就有這個防護,只是函式不同名。打開第 544 行才看到,它是在走訪 worktree 時算相對路徑,跟擋路徑穿越毫無關係。grep 命中的是同一個函式名,不是同一個用途。
所以這件事有兩層,而且都是我讀碼的推論。裝 release 的人,照我讀到的,沒有這個問題。追 main 的人,從 2025-08-26 到 2026-08-12 之間,是會碰到的。至於回報者說的「寫到 worktree 外面」到底能不能被利用、有多嚴重,我沒執行過,只有 issue 作者的描述。
四個多月沒人接球
issue 的原文很具體:
exportEnvironmentFilejoins a user-controlledtarget_filepath with the worktree base usingfilepath.Join, then writes to the result. Go’sfilepath.Joincleans..sequences but does not enforce a directory boundary.
意思是 ../../.bashrc 這種輸入,解出來會是 worktree 外面的合法路徑,函式照寫。出處是 issue #337。
單子開了之後,main 的動靜很稀。2026-02-23 之後,main 只進了 2026-06-12 一筆 commit,下一批要等到 2026-08-11。issue 底下 5 月 3 日有人留言,建議如果安全問題沒人顧得了,就考慮讓專案退休,原話是 “please consider retiring the project, if its security can no longer be maintained.”。兩天後被點名的那個帳號 cwlbraa 回:”i am no longer a maintainer, i left dagger in september.” 他寫了月份,沒寫哪一年。
順帶一個巧合:cwlbraa 也是 a10f338 的作者,就是引入那個函式的帳號。我只確認兩處的帳號名相同,不替任何人定責。
一秒
8 月 11 日,PR #360 被 grouville 合併,標題 “chore: sync maintenance fixes from fork”,作者 awdemos,內文有一句 “Originally developed on awdemos/container-use.”。隔天(UTC 02:53),同一位作者開了 PR #365,標題 “fix(repository): prevent path traversal in exportEnvironmentFile”,下午 16:30:35 合併。
修法不長:新增 validateExportFilePath,拒絕絕對路徑,filepath.Clean 之後以 .. 開頭的也拒絕,最後用 filepath.Rel 確認結果沒有逃出 worktree 根。commit 訊息寫明 “Based on the bug report in” issue #337。從 issue 開到關是 147 天。
問題是這個修補和前面那批 maintenance 修正,現在都只活在 main。下面這張表是我把兩個版本的同一批檔案並排讀的結果:
| 項目 | v0.4.2(2025-08-19 發布) | main(2026-11-06 查) |
|---|---|---|
exportEnvironmentFile |
0 次 | 有,並有 validateExportFilePath |
| git 操作的 hooks 設定 | git.go 內 hooksPath 0 次 |
第 27 至 30 行 noHooks = "core.hooksPath=/dev/null" |
dagger.json 的 engineVersion |
v0.18.14 | v0.21.8 |
go.mod 的 Go 版本 |
go 1.24.3 | go 1.26.1 |
| 與 v0.4.2 的距離 | 0 | ahead_by 27 |
第二列來自 main 上的 PR #362,commit 訊息說它讓 container-use 對你的 repo 做的所有 git 操作都帶 -c core.hooksPath=/dev/null,你自己的 pre-push、commit lint 不會被它觸發。v0.4.2 沒有這個設定。所以 main 和 release 差的不只是那一個修補,連依賴的 Dagger engine 都差了好幾版。
這 27 個 commit 我只看過標題,裡面有十幾個 dependabot 和 docs,我不會把它們說成 27 個修補。
用日期推,會推錯
我本來想用日期判斷某個功能在不在 v0.4.2 裡,這條路走不通。PR #273 讓 agent 可以指定 git ref 建立環境,日期是 2025-08-13,比 v0.4.2 的發布日早六天,我以為它在 release 裡。結果它在 compare 的那 27 個 commit 裡,也就是不在 v0.4.2。我只查到 v0.4.2 這個 tag 指向的 commit 是 89ebe77,日期是 2025-08-15,不是發布當天的那一刻;日期和 compare 為什麼對不上,我沒查清楚。
後來我一律用 compare 或 contents?ref=<tag> 逐檔驗。這比看日期慢,但日期看起來合理,那才危險。
五個說法互相對不上
這個專案還活著嗎?我手上有一堆訊號,彼此不一致:
- 4,086 顆星、215 fork、33 位 contributor(2026-11-06 查),
archived是 false,授權 Apache-2.0。 - GitHub 的
pushed_at是 2026-09-21,但 main 最後一個 commit 是 2026-08-12。這個落差我沒查出原因。 - 最新 release 是 2025-08-19。
- 公開留言裡,一位留言者說自己已經離開。
- README 徽章寫
stability-experimental,第 35 行寫 “This project is in early development and actively evolving.”
我不會從這些推出「專案已經棄置」。專案沒有說過,我也沒有證據。能下的結論窄得多:issue 被關掉,和使用者拿到修補,是兩件不同的事。我之前寫過另一個專案 kagent,那邊是 releases/latest 抓到 prerelease。這個專案相反,沒有 prerelease 這回事,只是最新的 release 比 main 舊 27 個 commit。
我的立場:想在放著真實 repo 的機器上用它,我會釘在 v0.4.2,不追 main。原因是已知的那一個問題只存在於 main,main 上這 27 個 commit 沒有任何一個經過發版流程(RELEASING.md 寫得很清楚,發版是手動打 tag、手動按 Publish),其中我沒逐筆讀過的部分,我不願意當成已經被人驗證過的東西。代價是少了 #362 那種 hooks 隔離,這我認。
會讓我改變想法的條件有兩個。第一,Dagger 發出一個含 2e43e62 的新 release,讓修補真的有版本號可以釘。第二,maintainer 公開說明這個專案接下來的打算。另外,如果你只在整台可以丟掉的機器上跑,這整篇的取捨都可以忽略。
自己查,五行就夠
1 | gh api repos/dagger/container-use/releases/latest --jq '.tag_name+" "+.published_at' |
我寫這篇時,這幾行回的是 v0.4.2、27、0、有命中、closed。14 個 release 之後,還沒有第 15 個。我最想知道的是,第 15 個真的出現的時候,它會從哪個 commit 切出來。










