Problem
#115 修好的是 model 欄位的詞法(lexical) containment——字串本身不可能含 ..、
絕對路徑或多層路徑。但檔案系統解析後的物理 containment 仍有缺口:若 model cache 目錄內
存在攻擊者可控的 symlink,cd "$MODEL_DIR" 解析後仍會離開 cache root。
Codex(跨模型 verify leg)給的具體情境:
CACHE_ROOT/openai_whisper-large-v3-turbo -> /etc
MODEL=large-v3-turbo # 完全合法、通過白名單
→ cd "$MODEL_DIR" 實際進入 /etc
甚至不需要 model 值有任何異常——合法值 + 惡意 symlink 就足夠。
Type
feature
Expected
若 symlink 納入 threat model,在 cd 之前:
- 對 cache root 與 target 做
realpath / resolve(strict=True)
- 用
os.path.commonpath() 或 Path.relative_to() 驗證 target 位於 root 之下
(不能只做字串 prefix 比對)
- 若存在可並行修改檔案系統的攻擊者,單純 realpath check 仍有 TOCTOU;強保證需要
dirfd / openat / O_NOFOLLOW 類設計
Impact
scripts/regression-gate.sh(model-pin 驗證段)、可能 scripts/pin-reference-model.sh
(見 #127,同一 sink)。
為什麼是 follow-up
DA 裁決:threat model 若只涵蓋「惡意 baseline 字串」且信任 cache 目錄結構,這不是 #126
的 blocker。#126 已經把過度絕對的註解改成誠實措辭(「LEXICAL containment — 假設 cache
tree 內無惡意 symlink」),所以 code 不再宣稱它沒有的保證——DA 把「先修註解」設為本
follow-up 可延後的前提條件,該條件已滿足。
誠實 severity:LOW-MEDIUM。需要攻擊者已能在 cache 目錄建立 symlink(該目錄由使用者
自己的 HF 快取構成),門檻高於惡意 PR。
Source: surfaced during /idd-verify PR #126 — Codex 跨模型 leg。三個 Claude lens 皆未提出。
Problem
#115 修好的是
model欄位的詞法(lexical) containment——字串本身不可能含..、絕對路徑或多層路徑。但檔案系統解析後的物理 containment 仍有缺口:若 model cache 目錄內
存在攻擊者可控的 symlink,
cd "$MODEL_DIR"解析後仍會離開 cache root。Codex(跨模型 verify leg)給的具體情境:
甚至不需要
model值有任何異常——合法值 + 惡意 symlink 就足夠。Type
feature
Expected
若 symlink 納入 threat model,在
cd之前:realpath/resolve(strict=True)os.path.commonpath()或Path.relative_to()驗證 target 位於 root 之下(不能只做字串 prefix 比對)
dirfd /
openat/O_NOFOLLOW類設計Impact
scripts/regression-gate.sh(model-pin 驗證段)、可能scripts/pin-reference-model.sh(見 #127,同一 sink)。
為什麼是 follow-up
DA 裁決:threat model 若只涵蓋「惡意 baseline 字串」且信任 cache 目錄結構,這不是 #126
的 blocker。#126 已經把過度絕對的註解改成誠實措辭(「LEXICAL containment — 假設 cache
tree 內無惡意 symlink」),所以 code 不再宣稱它沒有的保證——DA 把「先修註解」設為本
follow-up 可延後的前提條件,該條件已滿足。
誠實 severity:LOW-MEDIUM。需要攻擊者已能在 cache 目錄建立 symlink(該目錄由使用者
自己的 HF 快取構成),門檻高於惡意 PR。
Source: surfaced during /idd-verify PR #126 — Codex 跨模型 leg。三個 Claude lens 皆未提出。