diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index 72b4a49..9f77cf2 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1,12 +1,53 @@ { - "generatedAt": "2026/08/07 16:39:03", - "commitSha": "605d55745542fcd2ba4d2cc3317ba17fb4e35658", - "prNumber": null, + "generatedAt": "2026/08/08 00:46:03", + "commitSha": "ab384fe1080e5265724747a8faa960e4e960bf68", + "prNumber": 4, "tool": { "name": "ai-code-review", "version": "1.0.0", "model": "auto" }, - "findings": [], + "findings": [ + { + "level": "warning", + "role": "Mage", + "problem": "summarizeApiError 函式內存取 e.stderr 與 e.stdout 時未使用可選鏈,若 e 為 null 或 undefined,會拋出 TypeError 而非優雅容錯", + "suggestion": "改用可選鏈:`const stderr = e?.stderr || ''` 與 `const stdout = e?.stdout || ''`,或在函式開頭加入 `if (!e) return String(e);` 早期退出", + "location": "src/llm.js:161", + "is_new": false + }, + { + "level": "warning", + "role": "Assassin", + "location": "src/config.js:44", + "problem": "這裡只限制字元種類,卻還放行 `.` 與 `/`,因此像 `../foo`、`foo/../../bar` 這類路徑式字串仍可通過。攻擊者只要能控制 `inputs.model` 或 `CLI_PROXY_API_MODEL`,就能把惡意 model 值送進 CLIProxyAPI;若後端拿 model 名稱去拼路徑、呼叫指令或做檔名查找,這個輸入就可能被拿來做路徑穿越或指令注入。", + "suggestion": "不要只做字元白名單,應改成明確白名單比對可用模型 slug,並額外拒絕 `..`、前導/結尾 `/`、連續 `/`、反斜線與控制字元;如果可行,直接用 `/v1/models` 回傳清單做嚴格選擇,而不是接受任意形狀的字串。", + "is_new": true + }, + { + "level": "info", + "role": "Mage", + "problem": "mergeFindings 用 suggestion 前 50 字作為 key 的一部分進行去重。若兩個 findings 的 role 與 location 相同但 suggestion 在第 50 字之後才出現差異,會被誤判為重複而遭移除", + "suggestion": "考慮是否改用完整 suggestion 或增加其他識別字段(如 problem)來組成 key,確保去重不會誤刪本質不同的問題", + "location": "src/findings.js:349", + "is_new": false + }, + { + "level": "info", + "role": "Assassin", + "problem": "formatTimestamp 函數依賴 Intl.DateTimeFormat.formatToParts 的實現細節。若回應結構不符預期,`map.year`、`map.month` 等會是 `undefined`,導致日誌中顯示 `undefined` 字樣。雖然不影響安全性,但可能造成日誌混亂及除錯困難。", + "suggestion": "加強容錯處理。在存取 `map.year` 等屬性前先驗證其存在性;或改用更穩定的日期格式化方式(如 `new Date().toISOString()`)。同時增加單元測試,確保在異常情況下(例如不同的語言環境或舊版本瀏覽器)仍能產生正確的日誌格式。", + "location": "src/log.js:19", + "is_new": false + }, + { + "level": "info", + "role": "Assassin", + "location": "readme.md:9", + "problem": "這份新增文件把內部 Gitea 網域與完整倉庫路徑直接寫進專案內容。只要文件被外部看見,攻擊者就能先掌握內部服務命名、URL 模式與專案結構,降低枚舉、釣魚與後續橫向移動的成本。", + "suggestion": "如果這份文件有外部可見的可能,請把內網主機名與完整路徑改成相對路徑或 placeholder,並把只限內部使用的操作細節移到不對外公開的位置。", + "is_new": true + } + ], "excluded": [] }