canary-test-cli 5.0.0 → 5.2.0
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/package.json +1 -1
- package/scripts/install.js +11 -1
package/package.json
CHANGED
package/scripts/install.js
CHANGED
|
@@ -31,12 +31,22 @@ function getDownloadUrl(version, binaryName) {
|
|
|
31
31
|
return `https://github.com/bop-clocktower/canary/releases/download/v${version}/${binaryName}`;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
const TRUSTED_HOSTS = new Set(["github.com", "objects.githubusercontent.com"]);
|
|
35
|
+
|
|
36
|
+
function validateRedirectHost(location) {
|
|
37
|
+
const { hostname } = new URL(location);
|
|
38
|
+
if (!TRUSTED_HOSTS.has(hostname)) {
|
|
39
|
+
throw new Error(`Redirect to untrusted host: ${hostname}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
34
43
|
function download(url, destPath, redirectsLeft = 5) {
|
|
35
44
|
return new Promise((resolve, reject) => {
|
|
36
45
|
if (redirectsLeft === 0) return reject(new Error("Too many redirects"));
|
|
37
46
|
https.get(url, (res) => {
|
|
38
47
|
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
39
48
|
res.resume(); // drain redirect response to free the socket
|
|
49
|
+
try { validateRedirectHost(res.headers.location); } catch (e) { return reject(e); }
|
|
40
50
|
return resolve(download(res.headers.location, destPath, redirectsLeft - 1));
|
|
41
51
|
}
|
|
42
52
|
if (res.statusCode !== 200) {
|
|
@@ -69,5 +79,5 @@ async function main() {
|
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
// Export pure functions for testing; run main() only when executed directly.
|
|
72
|
-
module.exports = { getPlatformKey, getBinaryName, getDownloadUrl };
|
|
82
|
+
module.exports = { getPlatformKey, getBinaryName, getDownloadUrl, validateRedirectHost };
|
|
73
83
|
if (require.main === module) main().catch((e) => { process.stderr.write(e.message + "\n"); process.exit(1); });
|