123 lines
8.6 KiB
JSON
123 lines
8.6 KiB
JSON
[
|
||
{
|
||
"location": "action.yaml:23",
|
||
"role": "Assassin",
|
||
"original_finding": "將包含認證資訊的 `OAUTH` 透過環境變數傳遞,這使得該敏感資訊在容器內的任何進程皆可透過環境變數(如 `/proc/self/environ`)輕易竊取。",
|
||
"reason": "此 action 透過 Gitea/GitHub Docker Action input 接收 secret,action metadata 只能將 input 映射為容器環境變數;呼叫端仍使用 secrets.CODEX_OAUTH,未在 workflow 明文暴露。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:18",
|
||
"role": "Assassin",
|
||
"original_finding": "雖然有 `chmod 600`,但 `auth.json` 放在 `/root/.codex/` 目錄下,若發生容器逃逸,該敏感金鑰極易被讀取。",
|
||
"reason": "Codex CLI 目前需要讀取 CODEX_HOME/auth.json;容器內已限制為 600 權限,外部 Secret Store 掛載不是此 Docker Action 目前可控制的介面。"
|
||
},
|
||
{
|
||
"location": "action.yaml:6",
|
||
"role": "Leo",
|
||
"original_finding": "將 Base64 編碼的認證資訊設為 Action input,導致明文暴露在 Workflow 配置中,難以維護。",
|
||
"reason": "workflow 傳入的是 secrets.CODEX_OAUTH,不是明文值;使用 input 是 Docker Action 接收呼叫端 secret 的標準介面。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:22",
|
||
"role": "Rogue",
|
||
"original_finding": "在腳本中頻繁進行 I/O 操作(重複寫入 auth.json),缺乏快取檢查。",
|
||
"reason": "每次 Docker Action 執行都是短生命週期容器,auth.json 需要從當次 secret 重建;快取檢查不會降低跨執行 I/O,也可能增加 secret 狀態判斷複雜度。"
|
||
},
|
||
{
|
||
"location": "action.yaml:4",
|
||
"role": "Bard",
|
||
"original_finding": "輸入參數 `oauth` 實質為 base64 編碼的 json,命名易生誤解。",
|
||
"reason": "此 action 已對外發布並由既有 workflow 使用 oauth input;直接更名會造成破壞性變更,先保留相容介面與描述文字。"
|
||
},
|
||
{
|
||
"location": "Dockerfile:4",
|
||
"role": "Rogue",
|
||
"original_finding": "在 Dockerfile 中安裝了 git 且未清理,導致映像檔過大。",
|
||
"reason": "Codex CLI 與 plugin 安裝/執行流程可能需要 git 支援;為避免 runtime 缺少 git 造成 action 失敗,目前保留 git。"
|
||
},
|
||
{
|
||
"location": "Dockerfile:25",
|
||
"role": "Rogue",
|
||
"original_finding": "插件安裝指令採取連續序列執行,導致多次獨立的網路 I/O 等待,嚴重浪費建置時間。",
|
||
"reason": "codex plugin 指令會修改同一份本機 plugin 狀態,並行安裝可能造成狀態競爭;目前保留循序安裝以確保可預測性。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:22",
|
||
"role": "Leo",
|
||
"original_finding": "直接使用 `mktemp` 在 `CODEX_HOME` 目錄下建立臨時檔案,且 `CODEX_HOME` 若未正確隔離,在多個 Action 同時執行時可能會導致檔案名稱衝突。",
|
||
"reason": "Docker Action 每次執行都有獨立容器與 CODEX_HOME;mktemp 也會建立隨機檔名,實務上不會跨 action 執行衝突。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:16",
|
||
"role": "Leo",
|
||
"original_finding": "硬編碼了預設路徑 `/root/.codex`,這使得映像檔的可移植性受限,且如果在非 root 使用者環境下執行此容器,可能會因為權限問題而失敗。",
|
||
"reason": "Dockerfile 明確以 root 環境執行並設定 CODEX_HOME=/root/.codex;entrypoint 仍允許呼叫端用 CODEX_HOME 覆寫預設路徑。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:6",
|
||
"role": "Maya",
|
||
"original_finding": "應在測試案例中模擬空 OAUTH 輸入,並驗證腳本是否正確拋出錯誤並以 exit 1 終止。",
|
||
"reason": "AI 對話收斂判定為誤報(問題在最新程式碼中不成立或不適用)"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:11",
|
||
"role": "Maya",
|
||
"original_finding": "應在測試案例中模擬空 MODEL 輸入,並驗證腳本是否正確拋出錯誤並以 exit 1 終止。",
|
||
"reason": "AI 對話收斂判定為誤報(問題在最新程式碼中不成立或不適用)"
|
||
},
|
||
{
|
||
"location": "Dockerfile:17",
|
||
"role": "Bard",
|
||
"original_finding": "將安裝腳本邏輯直接寫在 `RUN` 指令中顯得冗長,且使用 `$(mktemp)` 容易產生難以追蹤的臨時檔案。",
|
||
"reason": "安裝流程需在同一 Docker layer 中下載、驗證 SHA-256、執行並清理暫存腳本;留在 Dockerfile 可讓供應鏈驗證步驟與安裝命令緊鄰,mktemp 產生的檔案也已於同一 RUN 中刪除。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:45",
|
||
"role": "Bard",
|
||
"original_finding": "使用靜態路徑檢查 `auth.json` 是否存在,若前次執行中斷導致檔案未清除,會導致後續執行失敗(Self-inflicted DoS)。",
|
||
"reason": "拒絕覆寫既有 auth.json 是刻意的 secret 安全保護,避免覆蓋呼叫端掛載或殘留的認證檔;Docker Action 預期每次執行使用獨立容器,前次中斷造成殘留的風險低於靜默覆寫 secret 的風險。"
|
||
},
|
||
{
|
||
"location": "tests/entrypoint_test.sh:17",
|
||
"role": "Bard",
|
||
"original_finding": "在測試中建立 `codex` 指令時,Here-document 與命令混雜,可讀性較低。",
|
||
"reason": "測試 helper 需要動態產生可執行的假 codex 指令,here-document 在此處比額外 fixture 檔更直觀且維持測試自含;此項屬風格偏好,不影響行為正確性。"
|
||
},
|
||
{
|
||
"location": "Dockerfile:10",
|
||
"role": "Assassin",
|
||
"original_finding": "Codex 外掛市集來源指向 `gitea.jsc.idv.tw`,未驗證來源的安全性。若該伺服器遭駭,將導致自動安裝惡意或篡改過的外掛,進而導致供應鏈攻擊。",
|
||
"reason": "Dockerfile 已使用 `codex plugin marketplace add --ref` 將 doc 與 code-review marketplace 固定到指定 commit SHA;此 action 需要安裝內部 Gitea marketplace 外掛,來源伺服器信任與存取控管屬部署環境治理,不適合在 Dockerfile 內改成其他來源。"
|
||
},
|
||
{
|
||
"location": "Dockerfile:24",
|
||
"role": "Leo",
|
||
"original_finding": "插件 URL 與版本參照 (REF) 硬編碼在 Dockerfile 中,未來若需更新插件或更換來源,需重新編譯整個 Docker 映像檔,維護成本較高。",
|
||
"reason": "此 Docker Action 需要可重現的建置結果;將 marketplace URL 與 ref 固定在 Dockerfile ARG 中,可讓外掛版本變更必須經由映像檔重建與 code review,避免外部設定在執行時靜默改變供應鏈內容。"
|
||
},
|
||
{
|
||
"location": "tests/entrypoint_test.sh:65",
|
||
"role": "Maya",
|
||
"original_finding": "測試案例對於輸入參數的邊界測試(例如 `PROMPT` 為空字串、極長字串)不足。",
|
||
"reason": "目前測試已包含 `test_empty_prompt` 與 `test_prompt_with_shell_characters`,覆蓋空字串與含 shell 特殊字元的 PROMPT 傳遞;此 finding 對最新測試內容已不成立。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:49",
|
||
"role": "Mage",
|
||
"original_finding": "在執行 install -m 600 時,若 codex 進程已經在嘗試讀取 auth.json,會發生檔案存取競態(Race Condition)。雖然使用了 flock,但這僅在同一個 shell 腳本實例中有效,無法保護跨容器或跨執行環境的檔案存取一致性。",
|
||
"reason": "最新入口已改為 `entrypoint.sh` 呼叫 `app/main.js`,不存在 `install -m 600`;Node.js 實作會先寫入並 chmod auth.json 後才啟動 codex,且 Docker Action 每次執行為獨立容器,跨容器不共享 CODEX_HOME。"
|
||
},
|
||
{
|
||
"location": "entrypoint.sh:58",
|
||
"role": "Mage",
|
||
"original_finding": "在容器化環境(通常是 ephemeral 的)中,auth.json 寫入後立刻被刪除,這會導致 codex 在後續執行中因找不到驗證檔案而無法運作。另外,trap 的清理機制會導致該檔案在 codex 完成工作前被刪除,這對於長效執行或需要多次存取的應用場景是錯誤的設計。",
|
||
"reason": "最新 Node.js 實作會等待 `codex exec` 子程序結束並寫入 output 後才執行 cleanup;auth.json 在 codex 執行期間持續存在,不會在工作完成前被刪除。"
|
||
},
|
||
{
|
||
"location": "Dockerfile:32",
|
||
"role": "Mage",
|
||
"original_finding": "在 Dockerfile 中直接使用 RUN 來下載並執行安裝腳本,沒有進行網路連接穩定性的驗證或完整的錯誤恢復機制。一旦網路不穩導致腳本不完整,後續的 sha256sum 檢查會失敗,但 Dockerfile 層疊技術可能會導致中間層殘留損壞的檔案。",
|
||
"reason": "Dockerfile 已在同一個 RUN 中完成下載、SHA-256 驗證與安裝,並使用 `curl --retry 3 --retry-delay 2 --max-time 120`;checksum 失敗會使該 layer 建置失敗,不會產生可用的損壞中間成果。"
|
||
}
|
||
]
|