@bryan-thompson/inspector-assessment-cli 1.16.1 → 1.18.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/build/cli.js +51 -14
- package/package.json +1 -1
package/build/cli.js
CHANGED
|
@@ -22,6 +22,20 @@ function isValidEnvVarName(name) {
|
|
|
22
22
|
function isValidEnvVarValue(value) {
|
|
23
23
|
return !value.includes("\0");
|
|
24
24
|
}
|
|
25
|
+
// [SECURITY-ENHANCEMENT] - triepod-ai fork: Block sensitive environment variables
|
|
26
|
+
const BLOCKED_ENV_VAR_PATTERNS = [
|
|
27
|
+
/^(AWS|AZURE|GCP|GOOGLE)_/i, // Cloud provider credentials
|
|
28
|
+
/^(API|AUTH|SECRET|TOKEN|KEY|PASSWORD|CREDENTIAL)_/i, // Generic secrets
|
|
29
|
+
/^(PRIVATE|SSH|PGP|GPG)_/i, // Private keys
|
|
30
|
+
/_(API_KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL)$/i, // Suffix patterns
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Check if an environment variable name should be blocked
|
|
34
|
+
* Prevents accidental exposure of sensitive credentials
|
|
35
|
+
*/
|
|
36
|
+
function isSensitiveEnvVar(name) {
|
|
37
|
+
return BLOCKED_ENV_VAR_PATTERNS.some((pattern) => pattern.test(name));
|
|
38
|
+
}
|
|
25
39
|
/**
|
|
26
40
|
* Validate and sanitize environment variables
|
|
27
41
|
* Returns filtered environment variables with invalid entries removed
|
|
@@ -37,10 +51,45 @@ function validateEnvVars(env) {
|
|
|
37
51
|
console.warn(`Warning: Skipping environment variable with invalid value: ${key}`);
|
|
38
52
|
continue;
|
|
39
53
|
}
|
|
54
|
+
// [SECURITY-ENHANCEMENT] - Block sensitive env vars
|
|
55
|
+
if (isSensitiveEnvVar(key)) {
|
|
56
|
+
console.warn(`Warning: Blocking potentially sensitive environment variable: ${key}`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
40
59
|
validated[key] = value;
|
|
41
60
|
}
|
|
42
61
|
return validated;
|
|
43
62
|
}
|
|
63
|
+
// [SECURITY-ENHANCEMENT] - triepod-ai fork: Unified SSRF protection patterns (matches client)
|
|
64
|
+
const PRIVATE_HOSTNAME_PATTERNS = [
|
|
65
|
+
// Localhost variants
|
|
66
|
+
/^localhost$/,
|
|
67
|
+
/^localhost\./,
|
|
68
|
+
// IPv4 private ranges
|
|
69
|
+
/^127\./, // 127.0.0.0/8 - loopback
|
|
70
|
+
/^10\./, // 10.0.0.0/8 - private
|
|
71
|
+
/^172\.(1[6-9]|2[0-9]|3[01])\./, // 172.16.0.0/12 - private
|
|
72
|
+
/^192\.168\./, // 192.168.0.0/16 - private
|
|
73
|
+
/^169\.254\./, // 169.254.0.0/16 - link-local
|
|
74
|
+
/^0\./, // 0.0.0.0/8 - current network
|
|
75
|
+
// IPv6 private ranges (enclosed in brackets for URL hostname)
|
|
76
|
+
/^\[::1\]$/, // ::1 - loopback
|
|
77
|
+
/^\[::ffff:127\./, // IPv4-mapped loopback
|
|
78
|
+
/^\[fe80:/i, // fe80::/10 - link-local
|
|
79
|
+
/^\[fc/i, // fc00::/7 - unique local
|
|
80
|
+
/^\[fd/i, // fd00::/8 - unique local
|
|
81
|
+
// Cloud metadata endpoints (common SSRF targets)
|
|
82
|
+
/^169\.254\.169\.254$/, // AWS/GCP metadata
|
|
83
|
+
/^metadata\./, // metadata.google.internal
|
|
84
|
+
];
|
|
85
|
+
/**
|
|
86
|
+
* Check if a hostname is a private/internal IP address
|
|
87
|
+
* Used to prevent SSRF attacks by blocking requests to internal networks
|
|
88
|
+
*/
|
|
89
|
+
function isPrivateHostname(hostname) {
|
|
90
|
+
const normalizedHostname = hostname.toLowerCase();
|
|
91
|
+
return PRIVATE_HOSTNAME_PATTERNS.some((pattern) => pattern.test(normalizedHostname));
|
|
92
|
+
}
|
|
44
93
|
/**
|
|
45
94
|
* Validate that a URL is safe for connection
|
|
46
95
|
* - Must be http or https
|
|
@@ -53,21 +102,9 @@ function validateServerUrl(url) {
|
|
|
53
102
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
54
103
|
throw new Error(`Invalid URL protocol: ${parsed.protocol}. Must be http or https.`);
|
|
55
104
|
}
|
|
56
|
-
// Block private IPs to prevent SSRF attacks
|
|
57
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
58
|
-
const privatePatterns = [
|
|
59
|
-
/^localhost$/,
|
|
60
|
-
/^127\./,
|
|
61
|
-
/^10\./,
|
|
62
|
-
/^172\.(1[6-9]|2[0-9]|3[01])\./,
|
|
63
|
-
/^192\.168\./,
|
|
64
|
-
/^169\.254\./, // Link-local
|
|
65
|
-
/^\[::1\]$/, // IPv6 localhost
|
|
66
|
-
/^\[fe80:/i, // IPv6 link-local
|
|
67
|
-
];
|
|
68
105
|
// Only warn for private IPs (don't block - may be intentional for local testing)
|
|
69
|
-
if (
|
|
70
|
-
console.warn(`Warning: Connecting to private/internal address: ${hostname}`);
|
|
106
|
+
if (isPrivateHostname(parsed.hostname)) {
|
|
107
|
+
console.warn(`Warning: Connecting to private/internal address: ${parsed.hostname}`);
|
|
71
108
|
}
|
|
72
109
|
}
|
|
73
110
|
catch (error) {
|
package/package.json
CHANGED