fix(release-cleanup): 強化輸入驗證、請求逾時與錯誤處理
解決 AI review 的安全性與健壯性問題: - 驗證 GITEA_SERVER_URL 為合法 http/https URL(降低 SSRF 風險) - 驗證 GITEA_REPOSITORY 為 owner/repo 形式並拒絕路徑穿越 - 為所有 fetch 請求加上 30 秒逾時(AbortSignal.timeout),避免卡死 - fetchAllPages 解析前檢查 content-type,非 JSON 時拋出明確錯誤 - selectReleasesToDelete 對無效 created_at 防呆,避免 NaN 排序 - index.js 匯出 main 並加上直接執行守衛,錯誤輸出含類型與堆疊 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1f27a46f7b
commit
154ab032bf
@@ -34,3 +34,35 @@ export function requireInteger(name, value) {
|
||||
throw new Error(`${name} must be a non-negative integer`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 要求值為合法的 http/https URL,藉此避免設定來源指向格式錯誤或非預期協定的伺服器(降低 SSRF 風險)。
|
||||
* @param {string} name 欄位名稱,用於組出錯誤訊息
|
||||
* @param {string} value 待檢查的 URL 字串
|
||||
* @throws {Error} 當 value 無法解析為 URL 時丟出 `${name} must be a valid URL`;
|
||||
* 協定非 http/https 時丟出 `${name} must use http or https protocol`
|
||||
*/
|
||||
export function requireUrl(name, value) {
|
||||
let url
|
||||
try {
|
||||
url = new URL(value)
|
||||
} catch {
|
||||
throw new Error(`${name} must be a valid URL`)
|
||||
}
|
||||
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
||||
throw new Error(`${name} must use http or https protocol`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 要求值為合法的 `owner/repo` 形式:僅允許英數字與 `. _ -`、恰好一個 `/`,且不可含路徑穿越片段 `..`。
|
||||
* 用於防止 GITEA_REPOSITORY 被竄改造成 API 目標被導向其他儲存庫。
|
||||
* @param {string} name 欄位名稱,用於組出錯誤訊息
|
||||
* @param {string} value 待檢查的 repository 字串
|
||||
* @throws {Error} 格式不符或含 `..` 時丟出 `${name} must be in the form owner/repo without path traversal`
|
||||
*/
|
||||
export function requireRepository(name, value) {
|
||||
if (String(value).includes('..') || !/^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/.test(value)) {
|
||||
throw new Error(`${name} must be in the form owner/repo without path traversal`)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user