diff --git a/.gitea/ai-review/exclusions.json b/.gitea/ai-review/exclusions.json index b8c4d13..e757b9d 100644 --- a/.gitea/ai-review/exclusions.json +++ b/.gitea/ai-review/exclusions.json @@ -52,5 +52,35 @@ "role": "Rogue", "original_finding": "在 ahead 為 0 時,仍執行昂貴的 diff 採集與分析;建議先執行 countAheadCommits,若 ahead === 0 則直接終止。", "reason": "現有程式已於 `countAheadCommits` 後立即檢查,`if (ahead === 0) { ...; return; }`(index.js:28-32)早於 diff 採集(index.js:36 起)就終止,與建議行為一致,屬誤報。" + }, + { + "location": "app/lib/opencode.js:180", + "role": "Assassin", + "original_finding": "AI 模型產生的 PR 描述未經 sanitization,易遭 Prompt Injection 導致 Stored XSS 攻擊;建議在 extractResult 對 obj.description 使用 HTML Sanitizer。", + "reason": "description 以 Markdown 文字經 API 寫入 Gitea PR body,HTML 的消毒由 Gitea 渲染端負責(Gitea 對使用者內容套用 HTML sanitizer policy),非本 action 職責。description 是 Markdown 而非 HTML,在 client 端套用 HTML Sanitizer 反而會破壞合法的 Markdown 內容。" + }, + { + "location": "app/lib/opencode.js:154", + "role": "Leo", + "original_finding": "summarize 函式使用 5 分鐘固定 timeout,大型 diff 可能導致分析失敗;建議改為可配置或依 diff 大小動態計算。", + "reason": "送入 opencode 的 diff 已於 index.js 以 maxDiffChars(60000 字元)截斷,prompt 大小有上限,5 分鐘對此規模輸入相當充裕;timeout 可配置屬增強而非缺陷。" + }, + { + "location": "app/lib/opencode.js:127", + "role": "Mage", + "original_finding": "summarize 方法中使用 spawnSync 執行指令,未處理退出訊號可能導致清理競態。", + "reason": "spawnSync 為同步阻塞呼叫,回傳後才執行 finally 清理,無並行清理路徑,不存在競態;timeout/訊號終止時 spawnSync 仍會回傳,finally 的 rmSync 必定執行。" + }, + { + "location": "app/lib/git.js:145", + "role": "Maya", + "original_finding": "合併衝突後未檢查是否存在殘留衝突標記;建議在 git add 後以 grep 掃描衝突標記。", + "reason": "createResolveBranch 刻意保留衝突標記並 commit,讓開發者在解衝突 PR 中看到並手動解決(PR body 亦明確要求解決 `<<<<<<<` 等標記),保留標記為設計核心;若在此偵測並失敗反而會破壞既定流程。" + }, + { + "location": "app/lib/opencode.js:40", + "role": "Rogue", + "original_finding": "頻繁寫入讀取 opencode.json 設定檔造成無謂的 I/O;建議透過參數或環境變數傳入配置。", + "reason": "summarize 每次 action 執行僅呼叫一次,並非「頻繁」;opencode 以 OPENCODE_CONFIG 指向設定檔為其官方配置介面,寫入單一小檔的 I/O 可忽略。" } ] diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index dcc8b2c..38dd569 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -13,13 +13,6 @@ "problem": "detectConflict 執行 git 合併失敗後的 abort 嘗試若失敗,會導致工作區殘留錯誤狀態,且未經測試。", "suggestion": "增加測試案例模擬 git 合併失敗與 abort 失敗的場景,確保狀態正確復原。" }, - { - "level": "critical", - "role": "Assassin", - "location": "app/lib/opencode.js:180", - "problem": "AI 模型產生的 PR 描述未經 sanitization,易遭 Prompt Injection 導致 Stored XSS 攻擊。", - "suggestion": "在 `extractResult` 中對 `obj.description` 使用成熟的 HTML Sanitizer 過濾惡意標籤。" - }, { "level": "warning", "role": "Maya", @@ -28,27 +21,6 @@ "suggestion": "補上針對 truncateDiff 及 commitMessages 為空/null 時的測試案例。", "is_new": false }, - { - "level": "warning", - "role": "Leo", - "location": "app/lib/opencode.js:154", - "problem": "summarize 函式使用了 5 分鐘固定 timeout,大型 diff 可能導致分析失敗。", - "suggestion": "將 timeout 設定為可配置參數或根據 diff 大小動態計算。" - }, - { - "level": "warning", - "role": "Mage", - "location": "app/lib/opencode.js:127", - "problem": "`summarize` 方法中使用 `spawnSync` 執行指令,未處理退出訊號可能導致清理競態。", - "suggestion": "明確處理 `spawnSync` 的退出訊號,並確保清理操作是原子性的。" - }, - { - "level": "warning", - "role": "Maya", - "location": "app/lib/git.js:145", - "problem": "合併衝突後未檢查是否存在殘留衝突標記。", - "suggestion": "在 `git add` 之後,使用 grep 掃描檔案中是否仍有未處理的衝突標記。" - }, { "level": "info", "role": "Maya", @@ -71,33 +43,5 @@ "location": "app/lib/opencode.js:77", "problem": "傳遞整個 `process.env` 導致敏感環境變數暴露。", "suggestion": "明確篩選並只傳遞必要環境變數。" - }, - { - "level": "info", - "role": "Bard", - "location": "Dockerfile:16", - "problem": "在 RUN 指令中使用 cd 切換目錄,導致環境隱晦。", - "suggestion": "使用 `WORKDIR /app`。" - }, - { - "level": "info", - "role": "Leo", - "location": "app/lib/git.js:122", - "problem": "臨時分支名稱可能衝突或殘留。", - "suggestion": "產生臨時分支名稱時加入 process ID 或隨機字串,並在 finally 區塊清理。" - }, - { - "level": "info", - "role": "Maya", - "location": "app/index.js:77", - "problem": "解衝突的 PR 產出缺乏人工檢查機制。", - "suggestion": "加入「檢查清單(Checklist)」要求人工確認。" - }, - { - "level": "info", - "role": "Rogue", - "location": "app/lib/opencode.js:40", - "problem": "頻繁寫入讀取 `opencode.json` 設定檔造成無謂的 I/O。", - "suggestion": "若支援,透過參數或環境變數傳入配置。" } ]