Files
release-cleanup/.gitea/ai-review/findings.json
T
JefferyandClaude Opus 4.8 b461f72d43
CI / AI Code Review (pull_request) Failing after 43s
chore(ai-review): 更新 findings.json 與 exclusions.json
移除已修復(決定性排序)與多項重複提報的 finding;保留 7 條設計取捨;
新增 6 條不適用/誤報至 exclusions(內部 IP 黑名單會破壞自架 Gitea、
section 排版主觀、無效日期已註記、CI 堆疊輸出無妨、MAX_PAGES 為安全上限、
通用 log 抽象效益低)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:43:16 +08:00

66 lines
4.0 KiB
JSON

[
{
"level": "warning",
"role": "Mage",
"location": "app/releases.js:38",
"problem": "清理流程對網路請求依賴強,若 API 呼叫失敗,整個 main 流程中斷,無法確保後續清理的一致性與部分成功重試。",
"suggestion": "引入更細緻的錯誤處理(如錯誤閾值機制)或部分清理成功後的重試策略。",
"status": "deferred",
"defer_reason": "錯誤處理/重試策略的設計取捨。目前單筆刪除失敗會記錄並繼續、讀取失敗則中止屬合理保守行為;是否引入閾值/重試保留待人工評估。"
},
{
"level": "warning",
"role": "Leo",
"location": "app/releases.js:37",
"problem": "cleanupReleases 同時處理資料獲取、邏輯判斷與副作用執行,違反單一職責原則。",
"suggestion": "拆分邏輯與執行層,將刪除副作用抽象化為獨立函式。",
"status": "deferred",
"defer_reason": "純邏輯(selectReleasesToDelete)已抽離且函式短小、已具失敗路徑/編碼/stderr/決定性排序測試;進一步拆出刪除迴圈為設計偏好,效益有限,保留待人工評估。"
},
{
"level": "warning",
"role": "Assassin",
"location": "app/gitea-client.js:66",
"problem": "錯誤路徑以 res.text() 讀取整個回應主體,未限制大小,惡意伺服器可回傳極大內容導致記憶體耗盡(DoS)。",
"suggestion": "限制讀取的回應大小,例如檢查 Content-Length 或以串流方式設定讀取上限。",
"status": "deferred",
"defer_reason": "風險低:目標為已通過 URL 驗證的受信任 Gitea 實例,且每請求已有 30 秒逾時。正確修法需串流逐段讀取並設位元組上限,屬較大改動,保留待人工評估。"
},
{
"level": "warning",
"role": "Assassin",
"location": "app/gitea-client.js:77",
"problem": "成功路徑以 res.json() 解析整個回應,未限制大小,惡意伺服器可回傳極大 JSON 導致記憶體耗盡(DoS)。",
"suggestion": "對 API 回應設定明確大小上限,超過時拒絕解析並拋出異常。",
"status": "deferred",
"defer_reason": "與 app/gitea-client.js:66 同類:受信任目標、已有逾時與 MAX_PAGES 約束,風險低;正確修法需串流讀取並設上限,屬較大改動,保留待人工評估。"
},
{
"level": "warning",
"role": "Assassin",
"location": "app/config.js:34",
"problem": "將環境變數值直接輸出至日誌,若內容含惡意字元或過長,可能造成 Log Injection 或日誌資源耗盡。",
"suggestion": "輸出前進行 sanitization,移除控制字元並限制長度,類似 gitea-client.js 的 sanitizeBody。",
"status": "deferred",
"defer_reason": "風險低:GITEA_SERVER_URL/GITEA_REPOSITORY/KEEP_COUNT 來自 CI 平台提供的 gitea context,並由 requireUrl/requireRepository/requireInteger 限定為不含控制字元的格式;log 注入需攻擊者控制 CI context 值才成立。可日後將記錄移至驗證後或加 sanitize,保留待人工評估。"
},
{
"level": "warning",
"role": "Assassin",
"location": "app/gitea-client.js:106",
"problem": "將 items 直接放入 all 陣列,若 API 回傳異常巨大的 JSON 陣列,可能導致容器記憶體耗盡(DoS)。",
"suggestion": "增加最大總項目數限制,並考慮以 AsyncGenerator 串流式處理降低記憶體佔用。",
"status": "deferred",
"defer_reason": "總量已受 MAX_PAGES(1000 頁)間接約束;改為 AsyncGenerator 串流處理屬較大架構改動,對 release/tag 數量有限的清理任務效益不高,保留待人工評估。"
},
{
"level": "info",
"role": "Bard",
"location": "app/releases.js:28",
"problem": "config 參數型別 ReturnType<import('./config.js').loadConfig> 雖準確但冗長,影響可讀性。",
"suggestion": "在 config.js 定義並匯出 JSDoc @typedef,於各處改用該別名。",
"status": "deferred",
"defer_reason": "純可讀性偏好,現有型別註解準確且可運作;引入 @typedef 會牽動多處 JSDoc 與 README 行號,效益有限,保留待人工評估。"
}
]