herozion 1.1.74 → 1.1.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/checksums.json +8 -0
- package/install.js +54 -26
- package/package.json +2 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "SHA-256 hashes for each platform binary. Auto-generated in CI from release CHECKSUMS.sha256. DO NOT edit manually.",
|
|
3
|
+
"_version": "1.1.75",
|
|
4
|
+
"herozion-linux-amd64": "42e718f60c1cfd3633a04e30c000bbb5311f15dd7222396b9bb7cba530570654",
|
|
5
|
+
"herozion-macos-amd64": "09a8aec95ac62df1bbe6f1b4f875248ce50ca9bf02ba2664e1f32d842f273ee7",
|
|
6
|
+
"herozion-macos-arm64": "441a7c237e5c7fb09c598dcfc7b4e3403d8d308768a8e2302110f39efeae5dd1",
|
|
7
|
+
"herozion-windows-amd64.exe": "9345261a6d986b327c2f68c9d21d687a0eb6c3622de1340e34149c418afbb4e5"
|
|
8
|
+
}
|
package/install.js
CHANGED
|
@@ -42,6 +42,13 @@ function getBinaryName() {
|
|
|
42
42
|
const { platform, arch } = process;
|
|
43
43
|
|
|
44
44
|
if (platform === "win32" && arch === "x64") return "herozion-windows-amd64.exe";
|
|
45
|
+
if (platform === "linux" && arch === "arm64") {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"Herozion: Linux ARM64 is not supported by the npm binary installer yet.\n" +
|
|
48
|
+
"Use: pip install herozion OR download from:\n" +
|
|
49
|
+
" https://github.com/Herozion/scanner-releases/releases/latest"
|
|
50
|
+
);
|
|
51
|
+
}
|
|
45
52
|
if (platform === "linux" && (arch === "x64" || arch === "ia32")) return "herozion-linux-amd64";
|
|
46
53
|
if (platform === "darwin" && arch === "arm64") return "herozion-macos-arm64";
|
|
47
54
|
if (platform === "darwin" && (arch === "x64" || arch === "ia32")) return "herozion-macos-amd64";
|
|
@@ -159,10 +166,22 @@ async function main() {
|
|
|
159
166
|
// ── Load bundled checksums (primary trust anchor) ─────────────────────────
|
|
160
167
|
const bundledChecksumsPath = path.join(__dirname, "bin", "checksums.json");
|
|
161
168
|
let bundledHash = "";
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
169
|
+
if (fs.existsSync(bundledChecksumsPath)) {
|
|
170
|
+
try {
|
|
171
|
+
const bundled = JSON.parse(fs.readFileSync(bundledChecksumsPath, "utf8"));
|
|
172
|
+
bundledHash = (bundled[binaryName] || "").toLowerCase().trim();
|
|
173
|
+
if (!bundledHash) {
|
|
174
|
+
console.warn(`herozion: WARNING — no bundled hash entry for ${binaryName}.`);
|
|
175
|
+
}
|
|
176
|
+
} catch (parseErr) {
|
|
177
|
+
console.warn(`herozion: WARNING — invalid checksums.json: ${parseErr.message}`);
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
console.warn(
|
|
181
|
+
"herozion: WARNING — bin/checksums.json missing from npm package; " +
|
|
182
|
+
"falling back to remote CHECKSUMS.sha256 verification."
|
|
183
|
+
);
|
|
184
|
+
}
|
|
166
185
|
|
|
167
186
|
console.log(`herozion: downloading ${binaryName} v${VERSION}...`);
|
|
168
187
|
try {
|
|
@@ -170,6 +189,8 @@ async function main() {
|
|
|
170
189
|
await download(url, tmpPath);
|
|
171
190
|
|
|
172
191
|
const actualHash = sha256File(tmpPath);
|
|
192
|
+
let bundledVerified = false;
|
|
193
|
+
let remoteVerified = false;
|
|
173
194
|
|
|
174
195
|
// ── Primary check: bundled checksum (trust anchor inside the npm package) ─
|
|
175
196
|
if (bundledHash) {
|
|
@@ -183,6 +204,7 @@ async function main() {
|
|
|
183
204
|
"This may indicate a supply-chain attack. Aborting installation."
|
|
184
205
|
);
|
|
185
206
|
}
|
|
207
|
+
bundledVerified = true;
|
|
186
208
|
}
|
|
187
209
|
|
|
188
210
|
// ── Secondary check: CHECKSUMS.sha256 from GitHub Releases ────────────────
|
|
@@ -198,56 +220,62 @@ async function main() {
|
|
|
198
220
|
}
|
|
199
221
|
return "";
|
|
200
222
|
})();
|
|
201
|
-
if (remoteHash
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
223
|
+
if (remoteHash) {
|
|
224
|
+
if (actualHash !== remoteHash) {
|
|
225
|
+
fs.unlinkSync(tmpPath);
|
|
226
|
+
throw new Error(
|
|
227
|
+
`Remote checksum mismatch for ${binaryName}.\n` +
|
|
228
|
+
` Expected (remote) : ${remoteHash}\n` +
|
|
229
|
+
` Got : ${actualHash}\n` +
|
|
230
|
+
"The downloaded binary does not match the GitHub Releases CHECKSUMS.sha256 file."
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
remoteVerified = true;
|
|
209
234
|
}
|
|
210
235
|
} catch (checksumErr) {
|
|
211
|
-
// If
|
|
212
|
-
if (!
|
|
236
|
+
// If bundled verification already passed, remote failure is non-fatal.
|
|
237
|
+
if (!bundledVerified) {
|
|
213
238
|
throw checksumErr;
|
|
214
239
|
}
|
|
215
240
|
console.warn(`herozion: WARNING — could not verify remote checksum: ${checksumErr.message}`);
|
|
216
241
|
console.warn("Proceeding because bundled checksum verification passed.");
|
|
217
242
|
}
|
|
218
243
|
|
|
219
|
-
// Fail closed:
|
|
220
|
-
if (!
|
|
221
|
-
// We reach here only when bundledHash is empty AND remote check was skipped/failed.
|
|
222
|
-
// Secondary catch block re-throws when !bundledHash, so this path is belt-and-suspenders.
|
|
244
|
+
// Fail closed: require at least one independent verification source.
|
|
245
|
+
if (!bundledVerified && !remoteVerified) {
|
|
223
246
|
fs.unlinkSync(tmpPath);
|
|
224
247
|
throw new Error(
|
|
225
|
-
`Cannot verify ${binaryName}: no bundled hash
|
|
248
|
+
`Cannot verify ${binaryName}: no bundled hash in package and remote checksum unavailable.\n` +
|
|
226
249
|
"Installation aborted to prevent supply-chain risk.\n" +
|
|
227
250
|
`Download manually from: ${BASE_URL}/${binaryName}`
|
|
228
251
|
);
|
|
229
252
|
}
|
|
230
253
|
|
|
231
|
-
//
|
|
254
|
+
// Verification passed — move binary into place
|
|
232
255
|
fs.renameSync(tmpPath, destPath);
|
|
233
256
|
if (!isWindows) {
|
|
234
257
|
fs.chmodSync(destPath, 0o755);
|
|
235
258
|
}
|
|
236
259
|
// Write version marker so we don't re-download on repeated installs
|
|
237
260
|
fs.writeFileSync(markerPath, VERSION, "utf8");
|
|
238
|
-
const verifiedBy =
|
|
261
|
+
const verifiedBy = bundledVerified && remoteVerified
|
|
262
|
+
? "bundled + remote SHA-256"
|
|
263
|
+
: bundledVerified
|
|
264
|
+
? "bundled SHA-256"
|
|
265
|
+
: "remote SHA-256";
|
|
239
266
|
console.log(`herozion: binary installed successfully (verified: ${verifiedBy}).`);
|
|
240
267
|
} catch (err) {
|
|
241
268
|
// Clean up temp file if it exists
|
|
242
269
|
try { fs.unlinkSync(tmpPath); } catch (_) {}
|
|
243
|
-
|
|
244
|
-
console.
|
|
245
|
-
console.
|
|
246
|
-
console.
|
|
270
|
+
console.error(`herozion: ERROR — could not install binary: ${err.message}`);
|
|
271
|
+
console.error("Try reinstalling with scripts enabled:");
|
|
272
|
+
console.error(" npm install herozion --foreground-scripts");
|
|
273
|
+
console.error(`Or download manually from: ${BASE_URL}/${binaryName}`);
|
|
274
|
+
process.exit(1);
|
|
247
275
|
}
|
|
248
276
|
}
|
|
249
277
|
|
|
250
278
|
main().catch((err) => {
|
|
251
279
|
console.error("herozion install error:", err.message);
|
|
252
|
-
|
|
280
|
+
process.exit(1);
|
|
253
281
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "herozion",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.75",
|
|
4
4
|
"description": "Security audit and performance analysis CLI tool for developers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"security",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"bin/herozion.js",
|
|
26
|
+
"bin/checksums.json",
|
|
26
27
|
"install.js",
|
|
27
28
|
"README.md"
|
|
28
29
|
],
|