barrikade-lens 0.1.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/LICENSE +21 -0
- package/README.md +117 -0
- package/bin/cli.js +37 -0
- package/package.json +51 -0
- package/src/exporters/html-exporter.js +683 -0
- package/src/exporters/json-exporter.js +17 -0
- package/src/runner.js +189 -0
- package/src/scanners/config-auditor.js +550 -0
- package/src/scanners/env-scanner.js +72 -0
- package/src/scanners/history-scanner.js +107 -0
- package/src/scanners/port-scanner.js +129 -0
- package/src/scanners/process-scanner.js +103 -0
- package/src/scanners/secret-scanner.js +88 -0
- package/src/ui/banner.js +26 -0
- package/src/ui/dashboard.js +67 -0
- package/src/ui/summary.js +139 -0
- package/src/ui/tables.js +258 -0
- package/src/utils/analyzer.js +418 -0
- package/src/utils/paths.js +293 -0
- package/src/utils/patterns.js +148 -0
- package/src/utils/telemetry.js +217 -0
package/src/runner.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { auditConfigs, auditWorkspaceArtifacts, auditDependencies } from './scanners/config-auditor.js';
|
|
5
|
+
import { scanPorts } from './scanners/port-scanner.js';
|
|
6
|
+
import { scanProcesses } from './scanners/process-scanner.js';
|
|
7
|
+
import { scanEnvFiles } from './scanners/env-scanner.js';
|
|
8
|
+
import { scanHistory } from './scanners/history-scanner.js';
|
|
9
|
+
import { scanConfigsForSecrets } from './scanners/secret-scanner.js';
|
|
10
|
+
import { analyzeCapabilities } from './utils/analyzer.js';
|
|
11
|
+
import { buildTelemetryPayload, promptTelemetryConsent, sendTelemetry } from './utils/telemetry.js';
|
|
12
|
+
import { displayDashboard } from './ui/dashboard.js';
|
|
13
|
+
import { exportJson } from './exporters/json-exporter.js';
|
|
14
|
+
import { exportHtml } from './exporters/html-exporter.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Executes the full capability-based security audit workflow.
|
|
18
|
+
*
|
|
19
|
+
* @param {{
|
|
20
|
+
* json?: boolean,
|
|
21
|
+
* report?: string,
|
|
22
|
+
* html?: string,
|
|
23
|
+
* telemetry?: boolean,
|
|
24
|
+
* verbose?: boolean
|
|
25
|
+
* }} options Command-line flags
|
|
26
|
+
* @returns {Promise<number>} Exit code (0 if clean, 1 if critical/high vulnerabilities found)
|
|
27
|
+
*/
|
|
28
|
+
export async function runAudit(options = {}) {
|
|
29
|
+
const isQuiet = options.json === true;
|
|
30
|
+
const isTelemetryOptOut = options.telemetry === false;
|
|
31
|
+
|
|
32
|
+
let spinner;
|
|
33
|
+
if (!isQuiet) {
|
|
34
|
+
spinner = ora({
|
|
35
|
+
text: 'Scanning workspace structures & active processes...',
|
|
36
|
+
color: 'yellow'
|
|
37
|
+
}).start();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
// 1. Audit config files
|
|
42
|
+
if (spinner) spinner.text = 'Auditing Shadow AI config files...';
|
|
43
|
+
const configs = await auditConfigs(process.cwd());
|
|
44
|
+
|
|
45
|
+
// 2. Audit workspace directories & rule files
|
|
46
|
+
if (spinner) spinner.text = 'Sweeping agent workspace structures & rule files...';
|
|
47
|
+
const workspaceArtifacts = await auditWorkspaceArtifacts(process.cwd());
|
|
48
|
+
|
|
49
|
+
// 3. Audit project dependencies
|
|
50
|
+
if (spinner) spinner.text = 'Analyzing project dependencies for agent frameworks...';
|
|
51
|
+
const depFrameworks = await auditDependencies(process.cwd());
|
|
52
|
+
|
|
53
|
+
// 4. Scan active processes
|
|
54
|
+
if (spinner) spinner.text = 'Detecting active AI and model inference processes...';
|
|
55
|
+
const processes = await scanProcesses();
|
|
56
|
+
|
|
57
|
+
// 5. Scan local LLM ports
|
|
58
|
+
if (spinner) spinner.text = 'Checking local model server ports...';
|
|
59
|
+
const ports = await scanPorts(300);
|
|
60
|
+
|
|
61
|
+
// 6. Scan environment files for secrets
|
|
62
|
+
if (spinner) spinner.text = 'Scanning workspace .env files for hardcoded secrets...';
|
|
63
|
+
const envSecrets = await scanEnvFiles(process.cwd());
|
|
64
|
+
|
|
65
|
+
// 7. Scan shell history for secrets & commands
|
|
66
|
+
if (spinner) spinner.text = 'Auditing shell history logs...';
|
|
67
|
+
const history = await scanHistory();
|
|
68
|
+
|
|
69
|
+
// 8. Scan configurations for secrets
|
|
70
|
+
if (spinner) spinner.text = 'Analyzing configuration blocks for plaintext credentials...';
|
|
71
|
+
const configSecrets = await scanConfigsForSecrets(configs);
|
|
72
|
+
|
|
73
|
+
if (spinner) {
|
|
74
|
+
spinner.stop();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Strip rawContent to ensure absolute user privacy in reports
|
|
78
|
+
for (const config of configs) {
|
|
79
|
+
delete config.rawContent;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Merge secrets findings from config files, env files, and shell history
|
|
83
|
+
const mergedSecrets = [
|
|
84
|
+
...configSecrets,
|
|
85
|
+
...envSecrets,
|
|
86
|
+
...history.findings
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
// 9. Run Capability Analysis
|
|
90
|
+
const capabilityResult = analyzeCapabilities({
|
|
91
|
+
configs,
|
|
92
|
+
workspace: workspaceArtifacts,
|
|
93
|
+
dependencies: depFrameworks,
|
|
94
|
+
processes,
|
|
95
|
+
ports,
|
|
96
|
+
secrets: mergedSecrets,
|
|
97
|
+
history
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// 10. Calculate metrics summary
|
|
101
|
+
const configsCount = configs.filter(c => c.exists).length;
|
|
102
|
+
const serversCount = configs.reduce((acc, c) => acc + (c.exists ? c.servers.length : 0), 0);
|
|
103
|
+
const portsScanned = ports.length;
|
|
104
|
+
const portsOpen = ports.filter(p => p.open).length;
|
|
105
|
+
const portsExposed = ports.filter(p => p.open && p.exposed).length;
|
|
106
|
+
const secretsCount = mergedSecrets.length;
|
|
107
|
+
|
|
108
|
+
const agentsCount = capabilityResult.agents.length;
|
|
109
|
+
const agentsActive = capabilityResult.agents.filter(a => a.status === 'ACTIVE').length;
|
|
110
|
+
const agentsInstalled = capabilityResult.agents.filter(a => a.status === 'INSTALLED').length;
|
|
111
|
+
|
|
112
|
+
const criticalCount = mergedSecrets.filter(s => s.risk === 'CRITICAL').length + portsExposed;
|
|
113
|
+
const highCount = mergedSecrets.filter(s => s.risk === 'HIGH').length;
|
|
114
|
+
const mediumCount = mergedSecrets.filter(s => s.risk === 'MEDIUM').length + configs.filter(c => c.exists && c.malformed).length;
|
|
115
|
+
|
|
116
|
+
const summary = {
|
|
117
|
+
configsCount,
|
|
118
|
+
serversCount,
|
|
119
|
+
portsScanned,
|
|
120
|
+
portsOpen,
|
|
121
|
+
portsExposed,
|
|
122
|
+
secretsCount,
|
|
123
|
+
criticalCount,
|
|
124
|
+
highCount,
|
|
125
|
+
mediumCount,
|
|
126
|
+
agentsCount,
|
|
127
|
+
agentsActive,
|
|
128
|
+
agentsInstalled
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const aggregatedResults = {
|
|
132
|
+
version: '0.1.0',
|
|
133
|
+
timestamp: new Date().toISOString(),
|
|
134
|
+
platform: os.platform(),
|
|
135
|
+
summary,
|
|
136
|
+
capabilities: capabilityResult.capabilities,
|
|
137
|
+
evidence: capabilityResult.evidence,
|
|
138
|
+
agents: capabilityResult.agents,
|
|
139
|
+
configs,
|
|
140
|
+
ports,
|
|
141
|
+
secrets: mergedSecrets
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// 12. Handle output formats
|
|
145
|
+
if (options.json) {
|
|
146
|
+
await exportJson(aggregatedResults);
|
|
147
|
+
} else {
|
|
148
|
+
displayDashboard(aggregatedResults);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Optional exports to files
|
|
152
|
+
if (options.report) {
|
|
153
|
+
await exportJson(aggregatedResults, options.report);
|
|
154
|
+
if (!isQuiet) {
|
|
155
|
+
console.log(chalk.green(`\n✔ JSON report written to: `) + chalk.white(options.report));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (options.html) {
|
|
160
|
+
await exportHtml(aggregatedResults, options.html);
|
|
161
|
+
if (!isQuiet) {
|
|
162
|
+
console.log(chalk.green(`✔ HTML CISO-Report written to: `) + chalk.white(options.html));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 13. Telemetry handling at the very end (prompt for consent or send silently in quiet mode)
|
|
167
|
+
if (!isTelemetryOptOut && process.env.BARRIKADE_NO_TELEMETRY !== '1' && process.env.BARRIKADE_NO_TELEMETRY !== 'true') {
|
|
168
|
+
const telemetryPayload = await buildTelemetryPayload(summary, capabilityResult.capabilities);
|
|
169
|
+
if (options.json) {
|
|
170
|
+
sendTelemetry(telemetryPayload).catch(() => { });
|
|
171
|
+
} else {
|
|
172
|
+
const consented = await promptTelemetryConsent(telemetryPayload, 15000);
|
|
173
|
+
if (consented) {
|
|
174
|
+
await sendTelemetry(telemetryPayload).catch(() => { });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Exit with 1 if there are any CRITICAL or HIGH findings, else 0
|
|
180
|
+
return (criticalCount > 0 || highCount > 0) ? 1 : 0;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (spinner) spinner.stop();
|
|
183
|
+
console.error(chalk.red('\n✖ Audit execution failed:'), error.message);
|
|
184
|
+
if (options.verbose) {
|
|
185
|
+
console.error(error);
|
|
186
|
+
}
|
|
187
|
+
return 1;
|
|
188
|
+
}
|
|
189
|
+
}
|