From 853401723d6d6622f431a3b4e6385bf65e8035b7 Mon Sep 17 00:00:00 2001 From: Zsolt Dollenstein Date: Wed, 13 May 2026 12:26:05 +0100 Subject: [PATCH] Limit GitHub tokens to github.com download URLs (#878) This makes the Astral mirror slightly less special. --- __tests__/download/download-version.test.ts | 24 ++++++++++++++++++++- dist/setup/index.cjs | 12 ++++++++--- src/download/download-version.ts | 19 ++++++++++++---- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/__tests__/download/download-version.test.ts b/__tests__/download/download-version.test.ts index 309116b..75147c3 100644 --- a/__tests__/download/download-version.test.ts +++ b/__tests__/download/download-version.test.ts @@ -223,7 +223,7 @@ describe("download-version", () => { ); }); - it("does not rewrite non-GitHub URLs", async () => { + it("does not send the token to non-GitHub URLs from the default manifest", async () => { mockGetArtifact.mockResolvedValue({ archiveFormat: "tar.gz", checksum: "abc123", @@ -241,8 +241,30 @@ describe("download-version", () => { expect(mockDownloadTool).toHaveBeenCalledWith( "https://example.com/uv.tar.gz", undefined, + undefined, + ); + }); + + it("does not send the token to GitHub lookalike hosts", async () => { + mockGetArtifact.mockResolvedValue({ + archiveFormat: "tar.gz", + checksum: "abc123", + downloadUrl: "https://github.com.evil.test/uv.tar.gz", + }); + + await downloadVersion( + "unknown-linux-gnu", + "x86_64", + "0.9.26", + undefined, "token", ); + + expect(mockDownloadTool).toHaveBeenCalledWith( + "https://github.com.evil.test/uv.tar.gz", + undefined, + undefined, + ); }); it("falls back to GitHub Releases when the mirror fails", async () => { diff --git a/dist/setup/index.cjs b/dist/setup/index.cjs index 2312eeb..3d35e3b 100644 --- a/dist/setup/index.cjs +++ b/dist/setup/index.cjs @@ -97007,7 +97007,6 @@ async function downloadVersion(platform2, arch3, version3, checksum, githubToken const resolvedChecksum = manifestUrl === void 0 ? checksum : resolveChecksum(checksum, artifact.checksum); const mirrorUrl = rewriteToMirror(artifact.downloadUrl); const downloadUrl = mirrorUrl ?? artifact.downloadUrl; - const downloadToken = mirrorUrl !== void 0 ? void 0 : githubToken; try { return await downloadArtifact( downloadUrl, @@ -97016,7 +97015,7 @@ async function downloadVersion(platform2, arch3, version3, checksum, githubToken arch3, version3, resolvedChecksum, - downloadToken + githubTokenForUrl(downloadUrl, githubToken) ); } catch (err) { if (mirrorUrl === void 0) { @@ -97032,7 +97031,7 @@ async function downloadVersion(platform2, arch3, version3, checksum, githubToken arch3, version3, resolvedChecksum, - githubToken + githubTokenForUrl(artifact.downloadUrl, githubToken) ); } } @@ -97042,6 +97041,13 @@ function rewriteToMirror(url2) { } return ASTRAL_MIRROR_PREFIX + url2.slice(GITHUB_RELEASES_PREFIX.length); } +function githubTokenForUrl(downloadUrl, githubToken) { + try { + return new URL(downloadUrl).origin === "https://github.com" ? githubToken : void 0; + } catch { + return void 0; + } +} async function downloadArtifact(downloadUrl, artifactName, platform2, arch3, version3, checksum, githubToken) { info(`Downloading uv from "${downloadUrl}" ...`); const downloadPath = await downloadTool( diff --git a/src/download/download-version.ts b/src/download/download-version.ts index fc86170..459ee5b 100644 --- a/src/download/download-version.ts +++ b/src/download/download-version.ts @@ -54,8 +54,6 @@ export async function downloadVersion( const mirrorUrl = rewriteToMirror(artifact.downloadUrl); const downloadUrl = mirrorUrl ?? artifact.downloadUrl; - // Don't send the GitHub token to the Astral mirror. - const downloadToken = mirrorUrl !== undefined ? undefined : githubToken; try { return await downloadArtifact( @@ -65,7 +63,7 @@ export async function downloadVersion( arch, version, resolvedChecksum, - downloadToken, + githubTokenForUrl(downloadUrl, githubToken), ); } catch (err) { if (mirrorUrl === undefined) { @@ -83,7 +81,7 @@ export async function downloadVersion( arch, version, resolvedChecksum, - githubToken, + githubTokenForUrl(artifact.downloadUrl, githubToken), ); } } @@ -100,6 +98,19 @@ export function rewriteToMirror(url: string): string | undefined { return ASTRAL_MIRROR_PREFIX + url.slice(GITHUB_RELEASES_PREFIX.length); } +function githubTokenForUrl( + downloadUrl: string, + githubToken: string, +): string | undefined { + try { + return new URL(downloadUrl).origin === "https://github.com" + ? githubToken + : undefined; + } catch { + return undefined; + } +} + async function downloadArtifact( downloadUrl: string, artifactName: string,