diff --git a/.gitea/ai-review/exclusions.json b/.gitea/ai-review/exclusions.json index f9a0b67..e42650b 100644 --- a/.gitea/ai-review/exclusions.json +++ b/.gitea/ai-review/exclusions.json @@ -28,5 +28,35 @@ "role": "Assassin", "original_finding": "移除 `--no-check-certificate`。若確實有無法解決的憑證問題,應排查來源網域的信任鏈或安裝正確的憑證,而不是直接關閉安全機制。", "reason": "AI 對話收斂判定為誤報(問題在最新程式碼中不成立或不適用)" + }, + { + "location": "app/index.js:41", + "role": "Assassin", + "original_finding": "Action 未對 GITEA_SERVER_URL 進行格式驗證,攻擊者若能控制 CI/CD 環境變數,即可將該值設定為惡意 URL,導致 GITEA_TOKEN 外洩。建議嚴格驗證格式並符合網域白名單。", + "reason": "GITEA_SERVER_URL 由 Gitea Actions 平台注入(gitea.server_url),非一般威脅模型下使用者可控;loadConfig 已加入 http/https URL 格式驗證;網域白名單屬各部署環境特定決策,不宜硬寫進通用 action。" + }, + { + "location": "app/index.js:18", + "role": "Maya", + "original_finding": "主邏輯函式 main 處理了 loadConfig 與 fetchReleases 的例外情境,但缺乏針對這些失敗路徑的整合測試。", + "reason": "前提已不成立:test/index.test.js 已以相依注入新增 main 成功路徑,以及 loadConfig 失敗、fetchReleases 失敗兩條失敗路徑的整合測試。" + }, + { + "location": "app/output.js:16", + "role": "Assassin", + "original_finding": "writeOutput 直接接收 file 路徑並 fs.appendFileSync 寫入,預設來源為 GITHUB_OUTPUT,存在任意檔案寫入/路徑穿越風險。建議對路徑加入嚴格驗證。", + "reason": "GITHUB_OUTPUT 由 Action runner 注入並指向授權的暫存輸出檔,寫入它正是回傳 step output 的標準機制;對通用 action 而言硬性限制路徑會破壞功能,且該變數於正常威脅模型中非使用者可控。" + }, + { + "location": "app/version.js:4", + "role": "Leo", + "original_finding": "版本號區段的進位上限(10)被直接硬編碼在程式中,未來調整進位規則需深入核心修改。建議設為配置常數或參數化。", + "reason": "進位上限已抽出為模組頂層具名常數 SEGMENT_LIMIT,可單點調整;進位規則為本 action 固定的業務規則,參數化屬尚無需求的過度設計。" + }, + { + "location": "app/logger.js:4", + "role": "Leo", + "original_finding": "日誌分隔線寬度與符號直接硬編碼在模組內,調整風格需改多處。建議集中管理並提供通用產生函數。", + "reason": "分隔線已是模組頂層集中定義的常數 LINE/SUBLINE,單點即可調整;為固定的視覺樣式再加產生函數屬過度設計。" } ] diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index 8d1368f..fe51488 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1,50 +1 @@ -[ - { - "level": "critical", - "role": "Assassin", - "problem": "Action 未對 `GITEA_SERVER_URL` 進行格式驗證,攻擊者若能控制 CI/CD 環境變數,即可將該值設定為惡意 URL,進而誘使 Action 將 `GITEA_TOKEN` 傳送至攻擊者伺服器,導致敏感憑證外洩。", - "suggestion": "在 `app/config.js` 的 `loadConfig` 中,對 `GITEA_SERVER_URL` 進行嚴格驗證,確保其格式正確(例如開頭必須為 `https://`)且符合預期的網域白名單(若適用)。", - "location": "app/index.js:41", - "is_new": false - }, - { - "level": "critical", - "role": "Maya", - "problem": "主邏輯函式 `main` 處理了 `loadConfig` 與 `fetchReleases` 的例外情境,但缺乏針對這些失敗路徑的整合測試,無法確保錯誤發生時流程能正確終止。", - "suggestion": "建議編寫整合測試,透過 mock 相關依賴(如 `loadConfig`、`fetchReleases`)來模擬錯誤,並驗證 `main` 是否正確觸發錯誤處理機制。", - "location": "app/index.js:18", - "is_new": false - }, - { - "level": "warning", - "role": "Assassin", - "location": "app/output.js:16", - "problem": "存在潛在的「任意檔案寫入」與「路徑穿越」風險。函式 `writeOutput` 直接接收 `file` 路徑並使用 `fs.appendFileSync` 進行寫入,且預設來源為環境變數 `GITHUB_OUTPUT`。若攻擊者能透過惡意配置篡改 CI/CD 環境變數,即可將任意資料寫入系統內的敏感檔案(如 /etc/passwd 或 SSH 授權金鑰),導致系統被入侵。", - "suggestion": "應對 `file` 路徑增加嚴格的驗證機制(Sanitization),確保其位於合法的臨時目錄或 CI/CD 授權的輸出路徑內,嚴禁寫入任意系統檔案路徑。", - "is_new": true - }, - { - "level": "warning", - "role": "Leo", - "location": "app/version.js:4", - "problem": "版本號區段的進位上限(10)被直接硬編碼在程式中。若未來業務需求需要調整進位規則,需要深入程式碼核心修改,容易遺漏或出錯。", - "suggestion": "建議將進位上限設為一個配置常數,或將其參數化,讓版本計算邏輯與進位策略分離。", - "is_new": true - }, - { - "level": "warning", - "role": "Maya", - "location": "app/releases.js:68", - "problem": "release API 解析 JSON 失敗時的例外路徑(Malformed JSON)未在測試中驗證,無法確認錯誤處理機制是否如預期運作。", - "suggestion": "在 test/releases.test.js 中新增一個測試案例,模擬 response.text() 回傳無法解析為 JSON 的字串,並驗證是否拋出預期的錯誤。", - "is_new": true - }, - { - "level": "info", - "role": "Leo", - "location": "app/logger.js:4", - "problem": "日誌的分隔線寬度與符號直接硬編碼在模組內。如果未來需要調整輸出風格,需要修改多個地方,且容易造成視覺不一致。", - "suggestion": "將分隔線寬度與符號定義為設定檔或在模組頂層集中管理,並考慮提供一個通用函數來產生這些分隔線。", - "is_new": true - } -] +[]