fix: harden proxied client installation
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s

This commit is contained in:
2026-08-18 16:01:06 +00:00
parent 40c5021c85
commit a08a2c1a96
15 changed files with 513 additions and 87 deletions
+13
View File
@@ -24,8 +24,16 @@ for (const [kind, artifact] of Object.entries(manifest.artifacts ?? {})) {
const expected = String(artifact.sha256 ?? "");
const actual = sha256(join(releaseDir, name));
if (!/^[a-f0-9]{64}$/.test(expected) || actual !== expected) throw new Error(`${kind} SHA-256 不匹配`);
for (const mirror of artifact.mirrors ?? []) {
const url = verifiedHttpsUrl(mirror, `${kind} mirror`);
if (basename(url.pathname) !== name) throw new Error(`${kind} mirror 文件名不一致`);
}
}
if (manifest.artifacts.publicKey.keyId !== keyId) throw new Error("publicKey artifact keyId 不匹配");
for (const mirror of manifest.distribution?.manifestMirrors ?? []) {
const url = verifiedHttpsUrl(mirror, "manifest mirror");
if (!url.pathname.endsWith("/manifest.json")) throw new Error("manifest mirror 必须指向 manifest.json");
}
const root = mkdtempSync(join(tmpdir(), "dingmcp-release-verify-"));
try {
@@ -113,6 +121,11 @@ function artifactName(value, kind) {
if (typeof url !== "string") throw new Error(`manifest 缺少 ${kind} URL`);
return basename(new URL(url).pathname);
}
function verifiedHttpsUrl(value, label) {
const url = new URL(String(value));
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash) throw new Error(`${label} 必须是 HTTPS URL`);
return url;
}
function sha256(path) { return createHash("sha256").update(readFileSync(path)).digest("hex"); }
function releaseKeyId(value) {
const der = createPublicKey(value).export({ type: "spki", format: "der" });