mirror of
https://github.com/alibaba/open-code-review.git
synced 2026-07-09 17:28:58 +00:00
fix: enforce mandatory checksum verification and HTTPS-only registry access
Previously, checksum failures in install.js were silently downgraded to warnings, allowing unverified binaries to be installed. Similarly, update.js accepted HTTP registries and skipped verification when no matching platform entry was found. Now both scripts treat checksum verification as mandatory when configured: all failure paths (download error, compute error, mismatch, missing platform entry) abort the operation and clean up downloaded files. update.js also drops the http module and silently skips version checks for non-HTTPS registries.
This commit is contained in:
parent
14d82ff0f0
commit
e9bd334b7f
2 changed files with 67 additions and 47 deletions
|
|
@ -189,37 +189,46 @@ async function main() {
|
|||
}
|
||||
|
||||
if (config.checksumPattern) {
|
||||
const checksumUrl = buildUrl(config.checksumPattern, vars);
|
||||
info("Verifying checksum...");
|
||||
let shaContent;
|
||||
try {
|
||||
const checksumUrl = buildUrl(config.checksumPattern, vars);
|
||||
info("Verifying checksum...");
|
||||
const shaContent = await downloadText(checksumUrl);
|
||||
const actualSha = await computeChecksum(binaryDest);
|
||||
shaContent = await downloadText(checksumUrl);
|
||||
} catch (e) {
|
||||
try { fs.unlinkSync(binaryDest); } catch (_) {}
|
||||
throw new Error(`Failed to download checksum from ${checksumUrl}: ${e.message}`);
|
||||
}
|
||||
let actualSha;
|
||||
try {
|
||||
actualSha = await computeChecksum(binaryDest);
|
||||
} catch (e) {
|
||||
try { fs.unlinkSync(binaryDest); } catch (_) {}
|
||||
throw new Error(`Failed to compute checksum for ${binaryDest}: ${e.message}`);
|
||||
}
|
||||
|
||||
let verified = false;
|
||||
for (const line of shaContent.split("\n")) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.includes(`-${os}-${arch}`)) {
|
||||
const expectedSha = trimmed.split(/\s+/)[0].toLowerCase();
|
||||
if (expectedSha) {
|
||||
if (actualSha !== expectedSha) {
|
||||
throw new Error(
|
||||
`Checksum mismatch! Expected: ${expectedSha}, Got: ${actualSha}`
|
||||
);
|
||||
}
|
||||
info("Checksum verified.");
|
||||
verified = true;
|
||||
break;
|
||||
let verified = false;
|
||||
for (const line of shaContent.split("\n")) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.includes(`-${os}-${arch}`)) {
|
||||
const expectedSha = trimmed.split(/\s+/)[0].toLowerCase();
|
||||
if (expectedSha) {
|
||||
if (actualSha !== expectedSha) {
|
||||
try { fs.unlinkSync(binaryDest); } catch (_) {}
|
||||
throw new Error(
|
||||
`Checksum mismatch! Expected: ${expectedSha}, Got: ${actualSha}`
|
||||
);
|
||||
}
|
||||
info("Checksum verified.");
|
||||
verified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!verified) {
|
||||
warn("No matching checksum entry found; skipping verification.");
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.message.includes("mismatch")) {
|
||||
throw e;
|
||||
}
|
||||
warn(`Could not verify checksum: ${e.message}`);
|
||||
}
|
||||
if (!verified) {
|
||||
try { fs.unlinkSync(binaryDest); } catch (_) {}
|
||||
throw new Error(
|
||||
`No matching checksum entry for ${os}-${arch} in ${checksumUrl}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const os = require("os");
|
||||
const http = require("http");
|
||||
const https = require("https");
|
||||
const { spawnSync } = require("child_process");
|
||||
|
||||
|
|
@ -85,14 +84,14 @@ function fetchLatestVersion(pkg) {
|
|||
if (!pkgName) return Promise.resolve(null);
|
||||
const encodedName = pkgName.replace(/\//g, "%2F");
|
||||
const url = `${registry.replace(/\/$/, "")}/${encodedName}/latest`;
|
||||
const client = url.startsWith("https") ? https : http;
|
||||
if (!url.startsWith("https://")) return Promise.resolve(null);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const options = {
|
||||
headers: { "User-Agent": "ocr-updater", Accept: "application/json" },
|
||||
timeout: 15000,
|
||||
};
|
||||
const req = client
|
||||
const req = https
|
||||
.get(url, options, (res) => {
|
||||
if (res.statusCode !== 200) {
|
||||
res.resume();
|
||||
|
|
@ -173,26 +172,38 @@ async function main() {
|
|||
}
|
||||
|
||||
if (config.checksumPattern) {
|
||||
const checksumUrl = buildUrl(config.checksumPattern, vars);
|
||||
let shaContent;
|
||||
try {
|
||||
const checksumUrl = buildUrl(config.checksumPattern, vars);
|
||||
const shaContent = await downloadText(checksumUrl);
|
||||
const actualSha = await computeChecksum(tempPath);
|
||||
|
||||
let verified = false;
|
||||
for (const line of shaContent.split("\n")) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.includes(`-${platform}-${arch}`)) {
|
||||
const expectedSha = trimmed.split(/\s+/)[0].toLowerCase();
|
||||
if (expectedSha && actualSha !== expectedSha) {
|
||||
fs.unlinkSync(tempPath);
|
||||
return;
|
||||
}
|
||||
verified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
shaContent = await downloadText(checksumUrl);
|
||||
} catch (_) {
|
||||
// checksum fetch failed, continue with the download
|
||||
fs.unlinkSync(tempPath);
|
||||
return;
|
||||
}
|
||||
let actualSha;
|
||||
try {
|
||||
actualSha = await computeChecksum(tempPath);
|
||||
} catch (_) {
|
||||
fs.unlinkSync(tempPath);
|
||||
return;
|
||||
}
|
||||
|
||||
let verified = false;
|
||||
for (const line of shaContent.split("\n")) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.includes(`-${platform}-${arch}`)) {
|
||||
const expectedSha = trimmed.split(/\s+/)[0].toLowerCase();
|
||||
if (expectedSha && actualSha !== expectedSha) {
|
||||
fs.unlinkSync(tempPath);
|
||||
return;
|
||||
}
|
||||
verified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!verified) {
|
||||
fs.unlinkSync(tempPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue