bashbros 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 +453 -0
- package/dist/audit-MCFNGOIM.js +11 -0
- package/dist/audit-MCFNGOIM.js.map +1 -0
- package/dist/chunk-43W3RVEL.js +2910 -0
- package/dist/chunk-43W3RVEL.js.map +1 -0
- package/dist/chunk-4R4GV5V2.js +213 -0
- package/dist/chunk-4R4GV5V2.js.map +1 -0
- package/dist/chunk-7OCVIDC7.js +12 -0
- package/dist/chunk-7OCVIDC7.js.map +1 -0
- package/dist/chunk-CSRPOGHY.js +354 -0
- package/dist/chunk-CSRPOGHY.js.map +1 -0
- package/dist/chunk-DEAF6PYM.js +212 -0
- package/dist/chunk-DEAF6PYM.js.map +1 -0
- package/dist/chunk-DLP2O6PN.js +273 -0
- package/dist/chunk-DLP2O6PN.js.map +1 -0
- package/dist/chunk-GD5VNHIN.js +519 -0
- package/dist/chunk-GD5VNHIN.js.map +1 -0
- package/dist/chunk-ID2O2QTI.js +269 -0
- package/dist/chunk-ID2O2QTI.js.map +1 -0
- package/dist/chunk-J37RHCFJ.js +357 -0
- package/dist/chunk-J37RHCFJ.js.map +1 -0
- package/dist/chunk-SB4JS3GU.js +456 -0
- package/dist/chunk-SB4JS3GU.js.map +1 -0
- package/dist/chunk-SG752FZC.js +200 -0
- package/dist/chunk-SG752FZC.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +2448 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-CZMIGNPF.js +13 -0
- package/dist/config-CZMIGNPF.js.map +1 -0
- package/dist/config-parser-XHE7BC7H.js +13 -0
- package/dist/config-parser-XHE7BC7H.js.map +1 -0
- package/dist/db-EHQDB5OL.js +11 -0
- package/dist/db-EHQDB5OL.js.map +1 -0
- package/dist/display-IN4NRJJS.js +18 -0
- package/dist/display-IN4NRJJS.js.map +1 -0
- package/dist/engine-PKLXW6OF.js +9 -0
- package/dist/engine-PKLXW6OF.js.map +1 -0
- package/dist/index.d.ts +1498 -0
- package/dist/index.js +552 -0
- package/dist/index.js.map +1 -0
- package/dist/moltbot-DXZFVK3X.js +11 -0
- package/dist/moltbot-DXZFVK3X.js.map +1 -0
- package/dist/ollama-HY35OHW4.js +9 -0
- package/dist/ollama-HY35OHW4.js.map +1 -0
- package/dist/risk-scorer-Y6KF2XCZ.js +9 -0
- package/dist/risk-scorer-Y6KF2XCZ.js.map +1 -0
- package/dist/static/index.html +410 -0
- package/package.json +68 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
__require
|
|
4
|
+
} from "./chunk-7OCVIDC7.js";
|
|
5
|
+
|
|
6
|
+
// src/audit.ts
|
|
7
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
11
|
+
var MAX_ROTATED_LOGS = 5;
|
|
12
|
+
var AuditLogger = class {
|
|
13
|
+
constructor(policy) {
|
|
14
|
+
this.policy = policy;
|
|
15
|
+
const bashbrosDir = join(homedir(), ".bashbros");
|
|
16
|
+
if (!existsSync(bashbrosDir)) {
|
|
17
|
+
mkdirSync(bashbrosDir, { recursive: true, mode: 448 });
|
|
18
|
+
}
|
|
19
|
+
this.logPath = join(bashbrosDir, "audit.log");
|
|
20
|
+
this.lockPath = join(bashbrosDir, "audit.lock");
|
|
21
|
+
}
|
|
22
|
+
logPath;
|
|
23
|
+
lockPath;
|
|
24
|
+
log(entry) {
|
|
25
|
+
if (!this.policy.enabled) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const logLine = this.formatEntry(entry);
|
|
29
|
+
if (this.policy.destination === "local" || this.policy.destination === "both") {
|
|
30
|
+
this.writeLocal(logLine);
|
|
31
|
+
}
|
|
32
|
+
if (this.policy.destination === "remote" || this.policy.destination === "both") {
|
|
33
|
+
this.sendRemote(entry);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
formatEntry(entry) {
|
|
37
|
+
const status = entry.allowed ? "ALLOWED" : "BLOCKED";
|
|
38
|
+
const violations = entry.violations.length > 0 ? ` [${entry.violations.map((v) => v.type).join(", ")}]` : "";
|
|
39
|
+
const sanitizedCommand = entry.command.replace(/[\x00-\x1f\x7f]/g, "").slice(0, 1e3);
|
|
40
|
+
return `[${entry.timestamp.toISOString()}] ${status}${violations} (${entry.duration}ms) ${sanitizedCommand}
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* SECURITY FIX: Write with file locking and rotation
|
|
45
|
+
*/
|
|
46
|
+
writeLocal(logLine) {
|
|
47
|
+
try {
|
|
48
|
+
this.acquireLock();
|
|
49
|
+
try {
|
|
50
|
+
this.rotateIfNeeded();
|
|
51
|
+
appendFileSync(this.logPath, logLine, { mode: 384 });
|
|
52
|
+
} finally {
|
|
53
|
+
this.releaseLock();
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error("Failed to write audit log:", error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Simple file-based locking
|
|
61
|
+
*/
|
|
62
|
+
acquireLock() {
|
|
63
|
+
const maxAttempts = 10;
|
|
64
|
+
const waitMs = 50;
|
|
65
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
66
|
+
try {
|
|
67
|
+
writeFileSync(this.lockPath, String(process.pid), { flag: "wx" });
|
|
68
|
+
return;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (error.code === "EEXIST") {
|
|
71
|
+
try {
|
|
72
|
+
const stats = statSync(this.lockPath);
|
|
73
|
+
if (Date.now() - stats.mtimeMs > 5e3) {
|
|
74
|
+
try {
|
|
75
|
+
__require("fs").unlinkSync(this.lockPath);
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
this.sleep(waitMs);
|
|
82
|
+
} else {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
console.warn("Could not acquire audit log lock, proceeding without");
|
|
88
|
+
}
|
|
89
|
+
releaseLock() {
|
|
90
|
+
try {
|
|
91
|
+
__require("fs").unlinkSync(this.lockPath);
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
sleep(ms) {
|
|
96
|
+
const end = Date.now() + ms;
|
|
97
|
+
while (Date.now() < end) {
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Rotate log if it exceeds max size
|
|
102
|
+
*/
|
|
103
|
+
rotateIfNeeded() {
|
|
104
|
+
try {
|
|
105
|
+
if (!existsSync(this.logPath)) return;
|
|
106
|
+
const stats = statSync(this.logPath);
|
|
107
|
+
if (stats.size < MAX_LOG_SIZE) return;
|
|
108
|
+
for (let i = MAX_ROTATED_LOGS - 1; i >= 0; i--) {
|
|
109
|
+
const oldPath = i === 0 ? this.logPath : `${this.logPath}.${i}`;
|
|
110
|
+
const newPath = `${this.logPath}.${i + 1}`;
|
|
111
|
+
if (existsSync(oldPath)) {
|
|
112
|
+
if (i === MAX_ROTATED_LOGS - 1) {
|
|
113
|
+
__require("fs").unlinkSync(oldPath);
|
|
114
|
+
} else {
|
|
115
|
+
renameSync(oldPath, newPath);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error("Failed to rotate audit log:", error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* SECURITY FIX: Secure remote transmission with HTTPS enforcement
|
|
125
|
+
*/
|
|
126
|
+
async sendRemote(entry) {
|
|
127
|
+
if (!this.policy.remotePath) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
let url;
|
|
131
|
+
try {
|
|
132
|
+
url = new URL(this.policy.remotePath);
|
|
133
|
+
} catch {
|
|
134
|
+
console.error("Invalid remote audit URL");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (url.protocol !== "https:") {
|
|
138
|
+
console.error("Remote audit path must use HTTPS");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const sanitizedEntry = {
|
|
142
|
+
timestamp: entry.timestamp.toISOString(),
|
|
143
|
+
command: entry.command.slice(0, 1e3),
|
|
144
|
+
// Limit size
|
|
145
|
+
allowed: entry.allowed,
|
|
146
|
+
violations: entry.violations.map((v) => ({
|
|
147
|
+
type: v.type,
|
|
148
|
+
rule: v.rule.slice(0, 200),
|
|
149
|
+
message: v.message.slice(0, 500)
|
|
150
|
+
})),
|
|
151
|
+
duration: entry.duration,
|
|
152
|
+
agent: entry.agent
|
|
153
|
+
};
|
|
154
|
+
try {
|
|
155
|
+
const controller = new AbortController();
|
|
156
|
+
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
157
|
+
await fetch(this.policy.remotePath, {
|
|
158
|
+
method: "POST",
|
|
159
|
+
headers: {
|
|
160
|
+
"Content-Type": "application/json",
|
|
161
|
+
"User-Agent": "BashBros/0.1.0"
|
|
162
|
+
},
|
|
163
|
+
body: JSON.stringify(sanitizedEntry),
|
|
164
|
+
signal: controller.signal
|
|
165
|
+
});
|
|
166
|
+
clearTimeout(timeout);
|
|
167
|
+
} catch (error) {
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
getLogPath() {
|
|
171
|
+
return this.logPath;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
async function viewAudit(options) {
|
|
175
|
+
const logPath = join(homedir(), ".bashbros", "audit.log");
|
|
176
|
+
if (!existsSync(logPath)) {
|
|
177
|
+
console.log("No audit log found. Run some commands first.");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const content = readFileSync(logPath, "utf-8");
|
|
181
|
+
let lines = content.trim().split("\n");
|
|
182
|
+
if (options.violations) {
|
|
183
|
+
lines = lines.filter((line) => line.includes("BLOCKED"));
|
|
184
|
+
}
|
|
185
|
+
const numLines = parseInt(options.lines, 10) || 50;
|
|
186
|
+
lines = lines.slice(-numLines);
|
|
187
|
+
for (const line of lines) {
|
|
188
|
+
if (line.includes("BLOCKED")) {
|
|
189
|
+
console.log("\x1B[31m" + line + "\x1B[0m");
|
|
190
|
+
} else {
|
|
191
|
+
console.log("\x1B[32m" + line + "\x1B[0m");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export {
|
|
197
|
+
AuditLogger,
|
|
198
|
+
viewAudit
|
|
199
|
+
};
|
|
200
|
+
//# sourceMappingURL=chunk-SG752FZC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/audit.ts"],"sourcesContent":["import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport type { AuditPolicy, AuditEntry } from './types.js'\n\n// Maximum log file size before rotation (10MB)\nconst MAX_LOG_SIZE = 10 * 1024 * 1024\n// Number of rotated logs to keep\nconst MAX_ROTATED_LOGS = 5\n\nexport class AuditLogger {\n private logPath: string\n private lockPath: string\n\n constructor(private policy: AuditPolicy) {\n const bashbrosDir = join(homedir(), '.bashbros')\n\n if (!existsSync(bashbrosDir)) {\n mkdirSync(bashbrosDir, { recursive: true, mode: 0o700 })\n }\n\n this.logPath = join(bashbrosDir, 'audit.log')\n this.lockPath = join(bashbrosDir, 'audit.lock')\n }\n\n log(entry: AuditEntry): void {\n if (!this.policy.enabled) {\n return\n }\n\n const logLine = this.formatEntry(entry)\n\n if (this.policy.destination === 'local' || this.policy.destination === 'both') {\n this.writeLocal(logLine)\n }\n\n if (this.policy.destination === 'remote' || this.policy.destination === 'both') {\n this.sendRemote(entry)\n }\n }\n\n private formatEntry(entry: AuditEntry): string {\n const status = entry.allowed ? 'ALLOWED' : 'BLOCKED'\n const violations = entry.violations.length > 0\n ? ` [${entry.violations.map(v => v.type).join(', ')}]`\n : ''\n\n // SECURITY: Sanitize command output (remove control characters)\n const sanitizedCommand = entry.command\n .replace(/[\\x00-\\x1f\\x7f]/g, '')\n .slice(0, 1000) // Limit command length in logs\n\n return `[${entry.timestamp.toISOString()}] ${status}${violations} (${entry.duration}ms) ${sanitizedCommand}\\n`\n }\n\n /**\n * SECURITY FIX: Write with file locking and rotation\n */\n private writeLocal(logLine: string): void {\n try {\n // Simple file-based locking\n this.acquireLock()\n\n try {\n // Check if rotation needed\n this.rotateIfNeeded()\n\n // Append to log\n appendFileSync(this.logPath, logLine, { mode: 0o600 })\n } finally {\n this.releaseLock()\n }\n } catch (error) {\n console.error('Failed to write audit log:', error)\n }\n }\n\n /**\n * Simple file-based locking\n */\n private acquireLock(): void {\n const maxAttempts = 10\n const waitMs = 50\n\n for (let i = 0; i < maxAttempts; i++) {\n try {\n // Try to create lock file exclusively\n writeFileSync(this.lockPath, String(process.pid), { flag: 'wx' })\n return\n } catch (error: any) {\n if (error.code === 'EEXIST') {\n // Lock exists, check if stale (older than 5 seconds)\n try {\n const stats = statSync(this.lockPath)\n if (Date.now() - stats.mtimeMs > 5000) {\n // Stale lock, remove it\n try {\n require('fs').unlinkSync(this.lockPath)\n } catch { /* ignore */ }\n }\n } catch { /* ignore */ }\n\n // Wait and retry\n this.sleep(waitMs)\n } else {\n throw error\n }\n }\n }\n\n // Fallback: proceed without lock (better than failing)\n console.warn('Could not acquire audit log lock, proceeding without')\n }\n\n private releaseLock(): void {\n try {\n require('fs').unlinkSync(this.lockPath)\n } catch { /* ignore */ }\n }\n\n private sleep(ms: number): void {\n const end = Date.now() + ms\n while (Date.now() < end) {\n // Busy wait (synchronous)\n }\n }\n\n /**\n * Rotate log if it exceeds max size\n */\n private rotateIfNeeded(): void {\n try {\n if (!existsSync(this.logPath)) return\n\n const stats = statSync(this.logPath)\n if (stats.size < MAX_LOG_SIZE) return\n\n // Rotate logs\n for (let i = MAX_ROTATED_LOGS - 1; i >= 0; i--) {\n const oldPath = i === 0 ? this.logPath : `${this.logPath}.${i}`\n const newPath = `${this.logPath}.${i + 1}`\n\n if (existsSync(oldPath)) {\n if (i === MAX_ROTATED_LOGS - 1) {\n // Delete oldest\n require('fs').unlinkSync(oldPath)\n } else {\n renameSync(oldPath, newPath)\n }\n }\n }\n } catch (error) {\n console.error('Failed to rotate audit log:', error)\n }\n }\n\n /**\n * SECURITY FIX: Secure remote transmission with HTTPS enforcement\n */\n private async sendRemote(entry: AuditEntry): Promise<void> {\n if (!this.policy.remotePath) {\n return\n }\n\n // SECURITY: Validate URL\n let url: URL\n try {\n url = new URL(this.policy.remotePath)\n } catch {\n console.error('Invalid remote audit URL')\n return\n }\n\n // SECURITY: Only allow HTTPS\n if (url.protocol !== 'https:') {\n console.error('Remote audit path must use HTTPS')\n return\n }\n\n // SECURITY: Sanitize entry before sending\n const sanitizedEntry = {\n timestamp: entry.timestamp.toISOString(),\n command: entry.command.slice(0, 1000), // Limit size\n allowed: entry.allowed,\n violations: entry.violations.map(v => ({\n type: v.type,\n rule: v.rule.slice(0, 200),\n message: v.message.slice(0, 500)\n })),\n duration: entry.duration,\n agent: entry.agent\n }\n\n try {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000) // 5s timeout\n\n await fetch(this.policy.remotePath, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'BashBros/0.1.0'\n },\n body: JSON.stringify(sanitizedEntry),\n signal: controller.signal\n })\n\n clearTimeout(timeout)\n } catch (error) {\n // Silently fail for remote - don't block main operation\n // Could implement retry queue here\n }\n }\n\n getLogPath(): string {\n return this.logPath\n }\n}\n\nexport async function viewAudit(options: { lines: string; violations: boolean }): Promise<void> {\n const logPath = join(homedir(), '.bashbros', 'audit.log')\n\n if (!existsSync(logPath)) {\n console.log('No audit log found. Run some commands first.')\n return\n }\n\n const content = readFileSync(logPath, 'utf-8')\n let lines = content.trim().split('\\n')\n\n if (options.violations) {\n lines = lines.filter(line => line.includes('BLOCKED'))\n }\n\n const numLines = parseInt(options.lines, 10) || 50\n lines = lines.slice(-numLines)\n\n for (const line of lines) {\n if (line.includes('BLOCKED')) {\n console.log('\\x1b[31m' + line + '\\x1b[0m') // Red\n } else {\n console.log('\\x1b[32m' + line + '\\x1b[0m') // Green\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.d.ts
ADDED