@ngcodes/ccpm 0.5.1 → 0.5.4
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/install.js +20 -3
- package/package.json +1 -1
package/install.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Downloads the correct ccpm binary for the current platform during npm install
|
|
3
3
|
|
|
4
|
-
const {
|
|
4
|
+
const { execFileSync } = require("child_process");
|
|
5
5
|
const crypto = require("crypto");
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
@@ -174,10 +174,14 @@ async function main() {
|
|
|
174
174
|
}
|
|
175
175
|
console.log(` sha256 ok (${expected})`);
|
|
176
176
|
|
|
177
|
+
// Extract via argv-array exec (no shell interpolation of paths). The
|
|
178
|
+
// archive content is already SHA-256-verified against the cosign-signed
|
|
179
|
+
// checksums manifest above, so residual zip-slip risk is accepted rather
|
|
180
|
+
// than adding a JS extractor dependency (itself supply-chain surface).
|
|
177
181
|
if (ext === "zip") {
|
|
178
|
-
|
|
182
|
+
execFileSync("unzip", ["-o", "-q", archivePath, "-d", tmpDir], { stdio: "inherit" });
|
|
179
183
|
} else {
|
|
180
|
-
|
|
184
|
+
execFileSync("tar", ["-xzf", archivePath, "-C", tmpDir], { stdio: "inherit" });
|
|
181
185
|
}
|
|
182
186
|
|
|
183
187
|
// Move the native binary to bin/ccpm-native (or ccpm-native.exe on Windows).
|
|
@@ -190,6 +194,19 @@ async function main() {
|
|
|
190
194
|
if (!fs.existsSync(extractedPath)) {
|
|
191
195
|
throw new Error(`extracted binary not found at ${extractedPath}`);
|
|
192
196
|
}
|
|
197
|
+
// Belt-and-braces: the file we are about to install must really live inside
|
|
198
|
+
// the temp dir (no symlink escape from a hostile archive).
|
|
199
|
+
const realExtracted = fs.realpathSync(extractedPath);
|
|
200
|
+
const realTmp = fs.realpathSync(tmpDir);
|
|
201
|
+
if (realExtracted !== path.join(realTmp, extractedName)) {
|
|
202
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
203
|
+
throw new Error(`extracted binary resolves outside the staging dir: ${realExtracted}`);
|
|
204
|
+
}
|
|
205
|
+
const extractedStat = fs.lstatSync(extractedPath);
|
|
206
|
+
if (!extractedStat.isFile()) {
|
|
207
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
208
|
+
throw new Error(`extracted binary is not a regular file`);
|
|
209
|
+
}
|
|
193
210
|
|
|
194
211
|
if (fs.existsSync(nativePath)) fs.unlinkSync(nativePath);
|
|
195
212
|
fs.renameSync(extractedPath, nativePath);
|