Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions src/utils/cve-to-ghsa.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { CResult } from '../types.mts'

/**
* Converts CVE IDs to GHSA IDs using GitHub API.
* CVE to GHSA mappings are permanent, so we cache for 30 days.
*/
export async function convertCveToGhsa(
cveId: string,
Expand All @@ -13,11 +14,16 @@ export async function convertCveToGhsa(
const cacheKey = `cve-to-ghsa-${cveId}`
const octokit = getOctokit()

const response = await cacheFetch(cacheKey, () =>
octokit.rest.securityAdvisories.listGlobalAdvisories({
cve_id: cveId,
per_page: 1,
}),
const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000

const response = await cacheFetch(
cacheKey,
() =>
octokit.rest.securityAdvisories.listGlobalAdvisories({
cve_id: cveId,
per_page: 1,
}),
THIRTY_DAYS_MS,
)

if (!response.data.length) {
Expand All @@ -32,9 +38,21 @@ export async function convertCveToGhsa(
data: response.data[0]!.ghsa_id,
}
} catch (e) {
const errorCause = getErrorCause(e)
const errorLower = errorCause.toLowerCase()
// Detect GitHub API rate limit and network errors.
const isRateLimitOrNetworkError =
errorLower.includes('rate limit') ||
errorLower.includes('epipe') ||
errorLower.includes('econnreset') ||
errorLower.includes('status: 403') ||
errorLower.includes('status code 403')

return {
ok: false,
message: `Failed to convert CVE to GHSA: ${getErrorCause(e)}`,
message: isRateLimitOrNetworkError
? 'GitHub API rate limit exceeded while converting CVE to GHSA. Wait an hour or set SOCKET_CLI_GITHUB_TOKEN environment variable with a personal access token for higher limits.'
: `Failed to convert CVE to GHSA: ${errorCause}`,
}
}
}