Skip to content

Commit c3277aa

Browse files
committed
Fixes to security issues identified
1 parent 032133d commit c3277aa

File tree

1 file changed

+30
-2
lines changed
  • catalog-analytics/app/api/github/ci-status

1 file changed

+30
-2
lines changed

catalog-analytics/app/api/github/ci-status/route.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,19 @@ function isValidRepoId(repo_id: string): boolean {
2121
return repoPattern.test(trimmed);
2222
}
2323

24+
function isValidCommitSha(sha: string): boolean {
25+
// Git SHAs are 40-character hexadecimal strings
26+
const shaPattern = /^[a-f0-9]{40}$/;
27+
return shaPattern.test(sha);
28+
}
29+
30+
function buildGitHubApiUrl(path: string): URL {
31+
// Always use the official GitHub API base URL to prevent SSRF
32+
const baseUrl = 'https://api.github.com';
33+
// URL constructor will throw if path is malformed
34+
return new URL(path, baseUrl);
35+
}
36+
2437
export async function POST(request: Request) {
2538
try {
2639
const { repositories }: CIStatusRequest = await request.json();
@@ -66,8 +79,10 @@ export async function POST(request: Request) {
6679

6780
try {
6881
// First, get the latest commit SHA on main branch
82+
// Use URL constructor to prevent SSRF
83+
const branchUrl = buildGitHubApiUrl(`/repos/${encodeURIComponent(repoIdStr)}/branches/main`);
6984
const branchResponse = await fetch(
70-
`https://api.github.com/repos/${repoIdStr}/branches/main`,
85+
branchUrl.toString(),
7186
{
7287
headers: {
7388
'Authorization': `Bearer ${token}`,
@@ -93,9 +108,22 @@ export async function POST(request: Request) {
93108
const branchData = await branchResponse.json();
94109
const latestCommitSha = branchData.commit.sha;
95110

111+
// Validate the commit SHA to prevent SSRF
112+
if (!isValidCommitSha(latestCommitSha)) {
113+
return {
114+
repo_id,
115+
state: 'unknown' as const,
116+
total_checks: 0,
117+
updated_at: new Date().toISOString(),
118+
details: 'Invalid commit SHA received from API',
119+
};
120+
}
121+
96122
// Now get check runs for this specific commit
123+
// Use URL constructor to prevent SSRF
124+
const checksUrl = buildGitHubApiUrl(`/repos/${encodeURIComponent(repoIdStr)}/commits/${latestCommitSha}/check-runs`);
97125
const checksResponse = await fetch(
98-
`https://api.github.com/repos/${repoIdStr}/commits/${latestCommitSha}/check-runs`,
126+
checksUrl.toString(),
99127
{
100128
headers: {
101129
'Authorization': `Bearer ${token}`,

0 commit comments

Comments
 (0)