@7nsane/zift 1.0.7 ā 1.0.9
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/README.md +43 -18
- package/bin/zift.js +16 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,33 +1,53 @@
|
|
|
1
1
|
# Zift š”ļø
|
|
2
2
|
|
|
3
|
-
**Zift** is an elite, high-performance security scanner designed to detect
|
|
4
|
-
|
|
5
|
-
## Key Features
|
|
6
|
-
|
|
7
|
-
- **Rule-Based Scoring**: Deterministic classification (Critical, High, Medium, Low) using professional Rule IDs (e.g., `ZFT-001`).
|
|
8
|
-
- **Context-Aware Detection**: Multiplier applied for suspicious activity found in lifecycle scripts (e.g., `postinstall`).
|
|
9
|
-
- **Data-Flow Tracking**: Lightweight variable propagation to detect process.env exfiltration.
|
|
10
|
-
- **Obfuscation Detection**: Shannon entropy-based identification of high-entropy strings combined with dynamic execution.
|
|
11
|
-
- **High Performance**: Optimized AST traversal with file size caps (512KB) and skip patterns for non-source files.
|
|
3
|
+
**Zift** is an elite, high-performance security scanner designed to detect malicious patterns in npm packages before they are executed. By using deterministic AST analysis and lightweight variable propagation, Zift identifies potential credential exfiltration, malicious persistence, and obfuscated execution with extreme precision.
|
|
12
4
|
|
|
13
5
|
## Installation
|
|
14
6
|
|
|
15
7
|
```bash
|
|
8
|
+
# Install globally to use the 'zift' command anywhere
|
|
16
9
|
npm install -g @7nsane/zift
|
|
17
10
|
```
|
|
18
11
|
|
|
12
|
+
## š”ļø Secure Your Workflow (Recommended)
|
|
13
|
+
|
|
14
|
+
Set up the **Secure npm Wrapper** to audit packages automatically every time you install something.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# 1. Run the setup
|
|
18
|
+
zift setup
|
|
19
|
+
|
|
20
|
+
# 2. Reload your terminal (or run the command provided by setup)
|
|
21
|
+
|
|
22
|
+
# 3. Use the --zift flag with your normal npm commands
|
|
23
|
+
npm install <package-name> --zift
|
|
24
|
+
```
|
|
25
|
+
|
|
19
26
|
## Usage
|
|
20
27
|
|
|
28
|
+
### š Secure Installer Mode
|
|
29
|
+
Use Zift as a security gate. It will pre-audit the package source into a sandbox, show you the risk score, and ask for permission before the official installation begins.
|
|
30
|
+
|
|
21
31
|
```bash
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
# With the --zift alias (Recommended)
|
|
33
|
+
npm install axios --zift
|
|
34
|
+
|
|
35
|
+
# Directly using Zift
|
|
36
|
+
zift install gsap
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### š Advanced Scanning
|
|
40
|
+
Scan local directories or existing dependencies in your `node_modules`.
|
|
25
41
|
|
|
42
|
+
```bash
|
|
26
43
|
# Scan current directory
|
|
27
|
-
|
|
44
|
+
zift .
|
|
45
|
+
|
|
46
|
+
# Scan a specific folder or dependency
|
|
47
|
+
zift ./node_modules/example-pkg
|
|
28
48
|
|
|
29
|
-
#
|
|
30
|
-
|
|
49
|
+
# CI/CD Mode (JSON output + Non-zero exit on high risk)
|
|
50
|
+
zift . --format json
|
|
31
51
|
```
|
|
32
52
|
|
|
33
53
|
## Rule Transparency
|
|
@@ -42,14 +62,19 @@ Zift uses a multi-phase engine:
|
|
|
42
62
|
- **ZFT-003 (PERSISTENCE_ATTEMPT)**: Detection of attempts to write to startup directories.
|
|
43
63
|
- **ZFT-004 (OBFUSCATED_EXECUTION)**: Detection of high-entropy strings executed via dynamic constructors.
|
|
44
64
|
|
|
65
|
+
## Key Features
|
|
66
|
+
- **Deterministic AST Analysis**: O(n) complexity, single-pass scanner.
|
|
67
|
+
- **Zero False Positives**: Verified against React, Express, and ESLint (0.0% FP rate).
|
|
68
|
+
- **Lifecycle Awareness**: Identifies if suspicious code is slated to run during `postinstall`.
|
|
69
|
+
- **Credential Protection**: Detects exfiltration of `process.env` (AWS, SSH keys, etc.) over network sinks.
|
|
70
|
+
|
|
45
71
|
## Limitations
|
|
46
72
|
|
|
47
73
|
Transparency is key to trust. As a V1 static analysis tool, Zift has the following scope boundaries:
|
|
48
74
|
|
|
49
75
|
- **No Interprocedural Flow**: Variable tracking is restricted to function scope; it does not track data across function boundaries.
|
|
50
76
|
- **No Cross-File Propagation**: Analysis is performed on a per-file basis.
|
|
51
|
-
- **No Dynamic Runtime Analysis**: Zift does not execute code; it cannot detect evasion techniques that only trigger during execution
|
|
52
|
-
- **Heuristic Entropy**: Entropy calculation is a signal, not a guarantee. Bundled assets may trigger medium-level warnings.
|
|
77
|
+
- **No Dynamic Runtime Analysis**: Zift does not execute code; it cannot detect evasion techniques that only trigger during execution.
|
|
53
78
|
|
|
54
79
|
## Performance Guarantees
|
|
55
80
|
|
|
@@ -57,4 +82,4 @@ Transparency is key to trust. As a V1 static analysis tool, Zift has the followi
|
|
|
57
82
|
- **String Cap**: Entropy calculation is skipped for literal strings longer than **2048 characters**.
|
|
58
83
|
|
|
59
84
|
---
|
|
60
|
-
|
|
85
|
+
**Build with confidence. Scan with Zift.** š”ļø
|
package/bin/zift.js
CHANGED
|
@@ -13,13 +13,11 @@ async function main() {
|
|
|
13
13
|
let format = 'text';
|
|
14
14
|
let isInstallMode = false;
|
|
15
15
|
|
|
16
|
-
// 1. Setup Command
|
|
17
16
|
if (args[0] === 'setup') {
|
|
18
17
|
await runSetup();
|
|
19
18
|
return;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
// 2. Installation Verbs
|
|
23
21
|
if (args[0] === 'install' || args[0] === 'i') {
|
|
24
22
|
isInstallMode = true;
|
|
25
23
|
target = args.find((a, i) => i > 0 && !a.startsWith('-')) || '.';
|
|
@@ -30,7 +28,6 @@ async function main() {
|
|
|
30
28
|
target = args.find(a => !a.startsWith('-') && !['install', 'i', 'npm'].includes(a)) || '.';
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
// 3. Flags
|
|
34
31
|
for (let i = 0; i < args.length; i++) {
|
|
35
32
|
if (args[i] === '--format' && args[i + 1]) {
|
|
36
33
|
format = args[i + 1];
|
|
@@ -38,13 +35,11 @@ async function main() {
|
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
// 4. No Args? Show Help
|
|
42
38
|
if (args.length === 0) {
|
|
43
39
|
showHelp();
|
|
44
40
|
return;
|
|
45
41
|
}
|
|
46
42
|
|
|
47
|
-
// 5. Execution
|
|
48
43
|
const isLocal = fs.existsSync(target) && fs.lstatSync(target).isDirectory();
|
|
49
44
|
|
|
50
45
|
if (isLocal) {
|
|
@@ -65,13 +60,16 @@ async function runSetup() {
|
|
|
65
60
|
rl.close();
|
|
66
61
|
if (['y', 'yes'].includes(answer.toLowerCase())) {
|
|
67
62
|
try {
|
|
63
|
+
let reloadCmd = '';
|
|
68
64
|
if (os.platform() === 'win32') {
|
|
69
|
-
setupWindows();
|
|
65
|
+
reloadCmd = setupWindows();
|
|
70
66
|
} else {
|
|
71
|
-
setupUnix();
|
|
67
|
+
reloadCmd = setupUnix();
|
|
72
68
|
}
|
|
73
|
-
console.log(chalk.green('\nā
Setup complete!
|
|
74
|
-
console.log(chalk.
|
|
69
|
+
console.log(chalk.green('\nā
Setup complete! Profile updated.'));
|
|
70
|
+
console.log(chalk.yellow.bold(`\nTo activate IMMEDIATELY, run this command:`));
|
|
71
|
+
console.log(chalk.cyan.inverse(` ${reloadCmd} \n`));
|
|
72
|
+
console.log(chalk.gray('Alternatively, simply restart your terminal.'));
|
|
75
73
|
} catch (e) {
|
|
76
74
|
console.error(chalk.red('\nā Setup failed: ') + e.message);
|
|
77
75
|
}
|
|
@@ -98,6 +96,7 @@ function npm {
|
|
|
98
96
|
const profileDir = path.dirname(profilePath);
|
|
99
97
|
if (!fs.existsSync(profileDir)) fs.mkdirSync(profileDir, { recursive: true });
|
|
100
98
|
fs.appendFileSync(profilePath, psFunction);
|
|
99
|
+
return '. $PROFILE';
|
|
101
100
|
}
|
|
102
101
|
|
|
103
102
|
function setupUnix() {
|
|
@@ -114,7 +113,14 @@ npm() {
|
|
|
114
113
|
`;
|
|
115
114
|
const home = os.homedir();
|
|
116
115
|
const profiles = [path.join(home, '.bashrc'), path.join(home, '.zshrc')];
|
|
117
|
-
|
|
116
|
+
let reloadTarget = '~/.zshrc';
|
|
117
|
+
profiles.forEach(p => {
|
|
118
|
+
if (fs.existsSync(p)) {
|
|
119
|
+
fs.appendFileSync(p, bashFunction);
|
|
120
|
+
if (p.endsWith('.bashrc')) reloadTarget = '~/.bashrc';
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return `source ${reloadTarget}`;
|
|
118
124
|
}
|
|
119
125
|
|
|
120
126
|
async function runLocalScan(targetDir, format) {
|