fivosense 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/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/.github/workflows/ci.yml +52 -0
- package/BLUEPRINT.md +215 -0
- package/BUILD_PLAN.md +175 -0
- package/CONTRIBUTING.md +80 -0
- package/DOCS_VERIFICATION.md +232 -0
- package/FINAL_CHECKLIST.md +263 -0
- package/FINAL_SUMMARY.md +238 -0
- package/GITHUB_PUSH.md +64 -0
- package/LICENSE +21 -0
- package/PROGRESS.md +153 -0
- package/README.md +443 -0
- package/RELEASE_READY.md +201 -0
- package/SECURITY.md +211 -0
- package/SECURITY_DEEP_AUDIT.md +331 -0
- package/TODO.md +52 -0
- package/dist/ai/judge.d.ts +36 -0
- package/dist/ai/judge.d.ts.map +1 -0
- package/dist/ai/judge.js +75 -0
- package/dist/ai/judge.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +39 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/editors/vscode.d.ts +30 -0
- package/dist/editors/vscode.d.ts.map +1 -0
- package/dist/editors/vscode.js +103 -0
- package/dist/editors/vscode.js.map +1 -0
- package/dist/engine/adversary.d.ts +24 -0
- package/dist/engine/adversary.d.ts.map +1 -0
- package/dist/engine/adversary.js +83 -0
- package/dist/engine/adversary.js.map +1 -0
- package/dist/engine/graph.d.ts +38 -0
- package/dist/engine/graph.d.ts.map +1 -0
- package/dist/engine/graph.js +131 -0
- package/dist/engine/graph.js.map +1 -0
- package/dist/engine/reach.d.ts +22 -0
- package/dist/engine/reach.d.ts.map +1 -0
- package/dist/engine/reach.js +107 -0
- package/dist/engine/reach.js.map +1 -0
- package/dist/engine/sinks.d.ts +52 -0
- package/dist/engine/sinks.d.ts.map +1 -0
- package/dist/engine/sinks.js +96 -0
- package/dist/engine/sinks.js.map +1 -0
- package/dist/engine/sources.d.ts +35 -0
- package/dist/engine/sources.d.ts.map +1 -0
- package/dist/engine/sources.js +59 -0
- package/dist/engine/sources.js.map +1 -0
- package/dist/engine/taint.d.ts +37 -0
- package/dist/engine/taint.d.ts.map +1 -0
- package/dist/engine/taint.js +83 -0
- package/dist/engine/taint.js.map +1 -0
- package/dist/engine/verify.d.ts +20 -0
- package/dist/engine/verify.d.ts.map +1 -0
- package/dist/engine/verify.js +65 -0
- package/dist/engine/verify.js.map +1 -0
- package/dist/features/badge.d.ts +20 -0
- package/dist/features/badge.d.ts.map +1 -0
- package/dist/features/badge.js +86 -0
- package/dist/features/badge.js.map +1 -0
- package/dist/features/fix.d.ts +20 -0
- package/dist/features/fix.d.ts.map +1 -0
- package/dist/features/fix.js +115 -0
- package/dist/features/fix.js.map +1 -0
- package/dist/features/roast.d.ts +23 -0
- package/dist/features/roast.d.ts.map +1 -0
- package/dist/features/roast.js +96 -0
- package/dist/features/roast.js.map +1 -0
- package/dist/hooks/agent.d.ts +19 -0
- package/dist/hooks/agent.d.ts.map +1 -0
- package/dist/hooks/agent.js +69 -0
- package/dist/hooks/agent.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +116 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/destructive.d.ts +35 -0
- package/dist/rules/destructive.d.ts.map +1 -0
- package/dist/rules/destructive.js +117 -0
- package/dist/rules/destructive.js.map +1 -0
- package/dist/rules/secrets.d.ts +29 -0
- package/dist/rules/secrets.d.ts.map +1 -0
- package/dist/rules/secrets.js +100 -0
- package/dist/rules/secrets.js.map +1 -0
- package/package.json +56 -0
- package/skill/SKILL.md +86 -0
- package/skill/prompts/path-judge.md +22 -0
- package/src/ai/judge.ts +100 -0
- package/src/cli/index.ts +46 -0
- package/src/editors/vscode.ts +125 -0
- package/src/engine/adversary.ts +100 -0
- package/src/engine/graph.ts +167 -0
- package/src/engine/reach.ts +141 -0
- package/src/engine/sinks.ts +113 -0
- package/src/engine/sources.ts +71 -0
- package/src/engine/taint.ts +117 -0
- package/src/engine/verify.ts +94 -0
- package/src/features/badge.ts +102 -0
- package/src/features/fix.ts +138 -0
- package/src/features/roast.ts +110 -0
- package/src/hooks/agent.ts +84 -0
- package/src/index.ts +147 -0
- package/src/rules/destructive.ts +131 -0
- package/src/rules/secrets.ts +120 -0
- package/test/engine.test.ts +110 -0
- package/test/features.test.ts +131 -0
- package/test/phase3.test.ts +129 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-fix Generator - Suggests and applies security fixes
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate fix for a vulnerability
|
|
6
|
+
*/
|
|
7
|
+
export function generateFix(trace, code) {
|
|
8
|
+
const { category, location } = trace;
|
|
9
|
+
switch (category) {
|
|
10
|
+
case 'sql':
|
|
11
|
+
return generateSQLFix(trace, code);
|
|
12
|
+
case 'xss':
|
|
13
|
+
return generateXSSFix(trace, code);
|
|
14
|
+
case 'command':
|
|
15
|
+
return generateCommandFix(trace, code);
|
|
16
|
+
default:
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate SQL injection fix
|
|
22
|
+
*/
|
|
23
|
+
function generateSQLFix(trace, code) {
|
|
24
|
+
// Extract the vulnerable line
|
|
25
|
+
const lines = code.split('\n');
|
|
26
|
+
const line = lines[trace.location.line - 1] || '';
|
|
27
|
+
// Detect query pattern
|
|
28
|
+
if (line.includes('db.execute') || line.includes('db.query')) {
|
|
29
|
+
return {
|
|
30
|
+
original: line.trim(),
|
|
31
|
+
fixed: line.replace(/`([^`]+)`/, (match, query) => {
|
|
32
|
+
// Convert template literal to parameterized query
|
|
33
|
+
const parameterized = query.replace(/\$\{([^}]+)\}/g, '?');
|
|
34
|
+
return `'${parameterized}', [${query.match(/\$\{([^}]+)\}/g)?.map((m) => m.slice(2, -1)).join(', ') || ''}]`;
|
|
35
|
+
}),
|
|
36
|
+
explanation: 'Use parameterized queries to prevent SQL injection',
|
|
37
|
+
confidence: 0.9,
|
|
38
|
+
type: 'parameterize',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
original: line.trim(),
|
|
43
|
+
fixed: line.trim(),
|
|
44
|
+
explanation: 'Manual review required - complex SQL pattern',
|
|
45
|
+
confidence: 0.5,
|
|
46
|
+
type: 'validate',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generate XSS fix
|
|
51
|
+
*/
|
|
52
|
+
function generateXSSFix(trace, code) {
|
|
53
|
+
const lines = code.split('\n');
|
|
54
|
+
const line = lines[trace.location.line - 1] || '';
|
|
55
|
+
if (line.includes('res.send')) {
|
|
56
|
+
return {
|
|
57
|
+
original: line.trim(),
|
|
58
|
+
fixed: line.replace(/res\.send\(([^)]+)\)/, 'res.send(escapeHtml($1))'),
|
|
59
|
+
explanation: 'Escape HTML to prevent XSS',
|
|
60
|
+
confidence: 0.85,
|
|
61
|
+
type: 'encode',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (line.includes('innerHTML')) {
|
|
65
|
+
return {
|
|
66
|
+
original: line.trim(),
|
|
67
|
+
fixed: line.replace(/\.innerHTML\s*=/, '.textContent ='),
|
|
68
|
+
explanation: 'Use textContent instead of innerHTML to prevent XSS',
|
|
69
|
+
confidence: 0.9,
|
|
70
|
+
type: 'encode',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
original: line.trim(),
|
|
75
|
+
fixed: line.trim(),
|
|
76
|
+
explanation: 'Manual review required - XSS context unclear',
|
|
77
|
+
confidence: 0.5,
|
|
78
|
+
type: 'encode',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Generate command injection fix
|
|
83
|
+
*/
|
|
84
|
+
function generateCommandFix(trace, code) {
|
|
85
|
+
const lines = code.split('\n');
|
|
86
|
+
const line = lines[trace.location.line - 1] || '';
|
|
87
|
+
if (line.includes('exec(')) {
|
|
88
|
+
return {
|
|
89
|
+
original: line.trim(),
|
|
90
|
+
fixed: line.replace(/exec\(([^)]+)\)/, 'execFile(command, args)'),
|
|
91
|
+
explanation: 'Use execFile with array arguments to prevent command injection',
|
|
92
|
+
confidence: 0.8,
|
|
93
|
+
type: 'validate',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
original: line.trim(),
|
|
98
|
+
fixed: line.trim(),
|
|
99
|
+
explanation: 'Validate and sanitize all command arguments',
|
|
100
|
+
confidence: 0.6,
|
|
101
|
+
type: 'validate',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Apply fix to code
|
|
106
|
+
*/
|
|
107
|
+
export function applyFix(code, fix, lineNumber) {
|
|
108
|
+
const lines = code.split('\n');
|
|
109
|
+
if (lineNumber < 1 || lineNumber > lines.length) {
|
|
110
|
+
return code;
|
|
111
|
+
}
|
|
112
|
+
lines[lineNumber - 1] = fix.fixed;
|
|
113
|
+
return lines.join('\n');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/features/fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Roast Mode - Generates viral, shareable roasts for insecure code
|
|
3
|
+
*/
|
|
4
|
+
import { AuditResult } from '../index.js';
|
|
5
|
+
export interface Roast {
|
|
6
|
+
title: string;
|
|
7
|
+
message: string;
|
|
8
|
+
severity: 'mild' | 'spicy' | 'brutal';
|
|
9
|
+
emoji: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generate roast based on audit results
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateRoast(result: AuditResult): Roast;
|
|
15
|
+
/**
|
|
16
|
+
* Format roast for display
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatRoast(roast: Roast): string;
|
|
19
|
+
/**
|
|
20
|
+
* Generate shareable roast badge
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateRoastBadge(result: AuditResult): string;
|
|
23
|
+
//# sourceMappingURL=roast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roast.d.ts","sourceRoot":"","sources":["../../src/features/roast.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAgDxD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAMhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAe9D"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Roast Mode - Generates viral, shareable roasts for insecure code
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate roast based on audit results
|
|
6
|
+
*/
|
|
7
|
+
export function generateRoast(result) {
|
|
8
|
+
const { summary } = result;
|
|
9
|
+
const total = summary.total;
|
|
10
|
+
const critical = summary.critical;
|
|
11
|
+
const high = summary.high;
|
|
12
|
+
if (total === 0) {
|
|
13
|
+
return {
|
|
14
|
+
title: 'Clean Code Champion',
|
|
15
|
+
message: '🎉 No vulnerabilities found! Your code is cleaner than your browser history.',
|
|
16
|
+
severity: 'mild',
|
|
17
|
+
emoji: '✨',
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (critical >= 3) {
|
|
21
|
+
return {
|
|
22
|
+
title: 'Security Nightmare',
|
|
23
|
+
message: `💀 ${critical} critical vulnerabilities? Even script kiddies are embarrassed for you. This code is more open than a 24/7 convenience store.`,
|
|
24
|
+
severity: 'brutal',
|
|
25
|
+
emoji: '💀',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (critical >= 1) {
|
|
29
|
+
return {
|
|
30
|
+
title: 'Living Dangerously',
|
|
31
|
+
message: `🔥 ${critical} critical issue(s) detected. Your code has more holes than Swiss cheese. SQL injection goes brrr.`,
|
|
32
|
+
severity: 'spicy',
|
|
33
|
+
emoji: '🔥',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (high >= 3) {
|
|
37
|
+
return {
|
|
38
|
+
title: 'Almost There',
|
|
39
|
+
message: `⚠️ ${high} high-severity issues. You're one XSS away from trending on HackerNews for the wrong reasons.`,
|
|
40
|
+
severity: 'spicy',
|
|
41
|
+
emoji: '⚠️',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
title: 'Needs Improvement',
|
|
46
|
+
message: `📝 ${total} security issue(s) found. Not terrible, but your future self will judge you.`,
|
|
47
|
+
severity: 'mild',
|
|
48
|
+
emoji: '📝',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Format roast for display
|
|
53
|
+
*/
|
|
54
|
+
export function formatRoast(roast) {
|
|
55
|
+
return `
|
|
56
|
+
${roast.emoji} ${roast.title} ${roast.emoji}
|
|
57
|
+
|
|
58
|
+
${roast.message}
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Generate shareable roast badge
|
|
63
|
+
*/
|
|
64
|
+
export function generateRoastBadge(result) {
|
|
65
|
+
const roast = generateRoast(result);
|
|
66
|
+
const grade = getSecurityGrade(result);
|
|
67
|
+
return `
|
|
68
|
+
## 🛡️ FivoSense Security Roast
|
|
69
|
+
|
|
70
|
+
**Grade:** ${grade}
|
|
71
|
+
**Verdict:** ${roast.title}
|
|
72
|
+
|
|
73
|
+
${roast.message}
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
Roasted by [FivoSense](https://github.com/fivosense) — Neuro-symbolic security scanner
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get security grade (A-F)
|
|
81
|
+
*/
|
|
82
|
+
function getSecurityGrade(result) {
|
|
83
|
+
const { summary } = result;
|
|
84
|
+
if (summary.total === 0)
|
|
85
|
+
return 'A+';
|
|
86
|
+
if (summary.critical === 0 && summary.high === 0)
|
|
87
|
+
return 'A';
|
|
88
|
+
if (summary.critical === 0 && summary.high <= 2)
|
|
89
|
+
return 'B';
|
|
90
|
+
if (summary.critical === 0)
|
|
91
|
+
return 'C';
|
|
92
|
+
if (summary.critical <= 1)
|
|
93
|
+
return 'D';
|
|
94
|
+
return 'F';
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=roast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roast.js","sourceRoot":"","sources":["../../src/features/roast.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAmB;IAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1B,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO;YACL,KAAK,EAAE,qBAAqB;YAC5B,OAAO,EAAE,8EAA8E;YACvF,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,GAAG;SACX,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO;YACL,KAAK,EAAE,oBAAoB;YAC3B,OAAO,EAAE,MAAM,QAAQ,+HAA+H;YACtJ,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO;YACL,KAAK,EAAE,oBAAoB;YAC3B,OAAO,EAAE,MAAM,QAAQ,mGAAmG;YAC1H,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACd,OAAO;YACL,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,MAAM,IAAI,+FAA+F;YAClH,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,mBAAmB;QAC1B,OAAO,EAAE,MAAM,KAAK,8EAA8E;QAClG,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,IAAI;KACZ,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,OAAO;EACP,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;;EAEzC,KAAK,CAAC,OAAO;CACd,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAEvC,OAAO;;;aAGI,KAAK;eACH,KAAK,CAAC,KAAK;;EAExB,KAAK,CAAC,OAAO;;;;CAId,CAAC;AACF,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,MAAmB;IAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAE3B,IAAI,OAAO,CAAC,KAAK,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAC7D,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAC5D,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACvC,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent PreToolUse Hook - Blocks dangerous AI actions in real-time
|
|
3
|
+
*/
|
|
4
|
+
export interface BlockResult {
|
|
5
|
+
blocked: boolean;
|
|
6
|
+
reason: string;
|
|
7
|
+
severity: 'critical' | 'high' | 'medium';
|
|
8
|
+
suggestion?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Check if proposed action should be blocked
|
|
12
|
+
*/
|
|
13
|
+
export declare function checkAction(action: string, code?: string): BlockResult;
|
|
14
|
+
/**
|
|
15
|
+
* PreToolUse hook for AI agents
|
|
16
|
+
* Returns exit code 2 if action should be blocked
|
|
17
|
+
*/
|
|
18
|
+
export declare function preToolUseHook(toolName: string, args: any): number;
|
|
19
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/hooks/agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CA8BtE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,CA8BlE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent PreToolUse Hook - Blocks dangerous AI actions in real-time
|
|
3
|
+
*/
|
|
4
|
+
import { detectDestructive } from '../rules/destructive.js';
|
|
5
|
+
import { detectSecrets } from '../rules/secrets.js';
|
|
6
|
+
/**
|
|
7
|
+
* Check if proposed action should be blocked
|
|
8
|
+
*/
|
|
9
|
+
export function checkAction(action, code) {
|
|
10
|
+
// Check for destructive commands
|
|
11
|
+
const destructive = detectDestructive(action);
|
|
12
|
+
if (destructive.length > 0) {
|
|
13
|
+
return {
|
|
14
|
+
blocked: true,
|
|
15
|
+
reason: `Destructive command detected: ${destructive[0].description}`,
|
|
16
|
+
severity: destructive[0].severity,
|
|
17
|
+
suggestion: 'Review the command carefully before executing',
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// Check for hardcoded secrets in code
|
|
21
|
+
if (code) {
|
|
22
|
+
const secrets = detectSecrets(code);
|
|
23
|
+
if (secrets.length > 0) {
|
|
24
|
+
return {
|
|
25
|
+
blocked: true,
|
|
26
|
+
reason: `Hardcoded secret detected: ${secrets[0].description}`,
|
|
27
|
+
severity: 'high',
|
|
28
|
+
suggestion: 'Use environment variables instead',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
blocked: false,
|
|
34
|
+
reason: '',
|
|
35
|
+
severity: 'medium',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* PreToolUse hook for AI agents
|
|
40
|
+
* Returns exit code 2 if action should be blocked
|
|
41
|
+
*/
|
|
42
|
+
export function preToolUseHook(toolName, args) {
|
|
43
|
+
// Check file write operations
|
|
44
|
+
if (toolName === 'write_file' || toolName === 'edit_file') {
|
|
45
|
+
const content = args.content || args.new_content || '';
|
|
46
|
+
const result = checkAction('', content);
|
|
47
|
+
if (result.blocked) {
|
|
48
|
+
console.error(`\n❌ BLOCKED: ${result.reason}`);
|
|
49
|
+
if (result.suggestion) {
|
|
50
|
+
console.error(`💡 Suggestion: ${result.suggestion}`);
|
|
51
|
+
}
|
|
52
|
+
return 2; // Exit code 2 signals block
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Check shell commands
|
|
56
|
+
if (toolName === 'bash' || toolName === 'execute') {
|
|
57
|
+
const command = args.command || args.cmd || '';
|
|
58
|
+
const result = checkAction(command);
|
|
59
|
+
if (result.blocked) {
|
|
60
|
+
console.error(`\n❌ BLOCKED: ${result.reason}`);
|
|
61
|
+
if (result.suggestion) {
|
|
62
|
+
console.error(`💡 Suggestion: ${result.suggestion}`);
|
|
63
|
+
}
|
|
64
|
+
return 2;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return 0; // Allow
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/hooks/agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AASpD;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,IAAa;IACvD,iCAAiC;IACjC,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,iCAAiC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACrE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ;YACjC,UAAU,EAAE,+CAA+C;SAC5D,CAAC;IACJ,CAAC;IAED,sCAAsC;IACtC,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,8BAA8B,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;gBAC9D,QAAQ,EAAE,MAAM;gBAChB,UAAU,EAAE,mCAAmC;aAChD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,QAAQ;KACnB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAS;IACxD,8BAA8B;IAC9B,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAExC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,kBAAkB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,CAAC,CAAC,CAAC,4BAA4B;QACxC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAEpC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,kBAAkB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC,CAAC,QAAQ;AACpB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FivoSense - Neuro-symbolic AI security plugin
|
|
3
|
+
* Entry point for the engine
|
|
4
|
+
*/
|
|
5
|
+
export interface AuditResult {
|
|
6
|
+
vulnerabilities: any[];
|
|
7
|
+
secrets: any[];
|
|
8
|
+
destructive: any[];
|
|
9
|
+
summary: {
|
|
10
|
+
total: number;
|
|
11
|
+
critical: number;
|
|
12
|
+
high: number;
|
|
13
|
+
medium: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Audit a file for security issues
|
|
18
|
+
*/
|
|
19
|
+
export declare function auditFile(filepath: string): Promise<AuditResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Audit code string for security issues
|
|
22
|
+
*/
|
|
23
|
+
export declare function auditCode(code: string, filename?: string): Promise<AuditResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Format audit result for display
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatAuditResult(result: AuditResult): string;
|
|
28
|
+
export * from './engine/graph.js';
|
|
29
|
+
export * from './engine/taint.js';
|
|
30
|
+
export * from './engine/sources.js';
|
|
31
|
+
export * from './engine/sinks.js';
|
|
32
|
+
export * from './rules/secrets.js';
|
|
33
|
+
export * from './rules/destructive.js';
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAKD;;GAEG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAStE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAsCzF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAoD7D;AAGD,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FivoSense - Neuro-symbolic AI security plugin
|
|
3
|
+
* Entry point for the engine
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, statSync } from 'fs';
|
|
6
|
+
import { buildDataFlowGraph } from './engine/graph.js';
|
|
7
|
+
import { generateTaintTraces, getVulnerableTraces, formatTrace } from './engine/taint.js';
|
|
8
|
+
import { detectSecrets } from './rules/secrets.js';
|
|
9
|
+
import { detectDestructive } from './rules/destructive.js';
|
|
10
|
+
// Security: Max file size to prevent memory exhaustion
|
|
11
|
+
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
|
12
|
+
/**
|
|
13
|
+
* Audit a file for security issues
|
|
14
|
+
*/
|
|
15
|
+
export async function auditFile(filepath) {
|
|
16
|
+
// Security check: File size limit
|
|
17
|
+
const stats = statSync(filepath);
|
|
18
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
19
|
+
throw new Error(`File too large: ${(stats.size / 1024 / 1024).toFixed(2)}MB (max ${MAX_FILE_SIZE / 1024 / 1024}MB)`);
|
|
20
|
+
}
|
|
21
|
+
const code = readFileSync(filepath, 'utf-8');
|
|
22
|
+
return auditCode(code, filepath);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Audit code string for security issues
|
|
26
|
+
*/
|
|
27
|
+
export async function auditCode(code, filename = 'input.js') {
|
|
28
|
+
// Security check: Code length
|
|
29
|
+
if (code.length > MAX_FILE_SIZE) {
|
|
30
|
+
throw new Error(`Code too large: ${(code.length / 1024 / 1024).toFixed(2)}MB (max ${MAX_FILE_SIZE / 1024 / 1024}MB)`);
|
|
31
|
+
}
|
|
32
|
+
// Build data-flow graph
|
|
33
|
+
const graph = buildDataFlowGraph(code, filename);
|
|
34
|
+
// Generate taint traces
|
|
35
|
+
const allTraces = generateTaintTraces(graph, filename);
|
|
36
|
+
const vulnerabilities = getVulnerableTraces(allTraces);
|
|
37
|
+
// Detect secrets
|
|
38
|
+
const secrets = detectSecrets(code);
|
|
39
|
+
// Detect destructive commands
|
|
40
|
+
const destructive = detectDestructive(code);
|
|
41
|
+
// Calculate summary
|
|
42
|
+
const criticalCount = vulnerabilities.filter(v => v.severity === 'critical').length +
|
|
43
|
+
destructive.filter(d => d.severity === 'critical').length;
|
|
44
|
+
const highCount = vulnerabilities.filter(v => v.severity === 'high').length +
|
|
45
|
+
secrets.length +
|
|
46
|
+
destructive.filter(d => d.severity === 'high').length;
|
|
47
|
+
const mediumCount = vulnerabilities.filter(v => v.severity === 'medium').length;
|
|
48
|
+
return {
|
|
49
|
+
vulnerabilities,
|
|
50
|
+
secrets,
|
|
51
|
+
destructive,
|
|
52
|
+
summary: {
|
|
53
|
+
total: vulnerabilities.length + secrets.length + destructive.length,
|
|
54
|
+
critical: criticalCount,
|
|
55
|
+
high: highCount,
|
|
56
|
+
medium: mediumCount,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Format audit result for display
|
|
62
|
+
*/
|
|
63
|
+
export function formatAuditResult(result) {
|
|
64
|
+
const lines = [];
|
|
65
|
+
lines.push('🛡️ FivoSense Security Audit\n');
|
|
66
|
+
lines.push('═'.repeat(50));
|
|
67
|
+
lines.push('');
|
|
68
|
+
// Summary
|
|
69
|
+
lines.push('📊 Summary:');
|
|
70
|
+
lines.push(` Total findings: ${result.summary.total}`);
|
|
71
|
+
lines.push(` Critical: ${result.summary.critical}`);
|
|
72
|
+
lines.push(` High: ${result.summary.high}`);
|
|
73
|
+
lines.push(` Medium: ${result.summary.medium}`);
|
|
74
|
+
lines.push('');
|
|
75
|
+
// Vulnerabilities
|
|
76
|
+
if (result.vulnerabilities.length > 0) {
|
|
77
|
+
lines.push('❌ Vulnerabilities:');
|
|
78
|
+
lines.push('');
|
|
79
|
+
result.vulnerabilities.forEach((vuln, i) => {
|
|
80
|
+
lines.push(`${i + 1}. ${formatTrace(vuln)}`);
|
|
81
|
+
lines.push('');
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Secrets
|
|
85
|
+
if (result.secrets.length > 0) {
|
|
86
|
+
lines.push('🔑 Hardcoded Secrets:');
|
|
87
|
+
lines.push('');
|
|
88
|
+
result.secrets.forEach((secret, i) => {
|
|
89
|
+
lines.push(`${i + 1}. [${secret.severity.toUpperCase()}] ${secret.description}`);
|
|
90
|
+
lines.push(` Line ${secret.line}: ${secret.match}`);
|
|
91
|
+
lines.push('');
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Destructive commands
|
|
95
|
+
if (result.destructive.length > 0) {
|
|
96
|
+
lines.push('💥 Destructive Commands:');
|
|
97
|
+
lines.push('');
|
|
98
|
+
result.destructive.forEach((cmd, i) => {
|
|
99
|
+
lines.push(`${i + 1}. [${cmd.severity.toUpperCase()}] ${cmd.description}`);
|
|
100
|
+
lines.push(` Category: ${cmd.category}`);
|
|
101
|
+
lines.push('');
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (result.summary.total === 0) {
|
|
105
|
+
lines.push('✅ No security issues found!');
|
|
106
|
+
}
|
|
107
|
+
return lines.join('\n');
|
|
108
|
+
}
|
|
109
|
+
// Export main functions
|
|
110
|
+
export * from './engine/graph.js';
|
|
111
|
+
export * from './engine/taint.js';
|
|
112
|
+
export * from './engine/sources.js';
|
|
113
|
+
export * from './engine/sinks.js';
|
|
114
|
+
export * from './rules/secrets.js';
|
|
115
|
+
export * from './rules/destructive.js';
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destructive command detection
|
|
3
|
+
* Blocks dangerous operations: rm -rf, DROP TABLE, mass deletes, etc.
|
|
4
|
+
*/
|
|
5
|
+
export interface DestructivePattern {
|
|
6
|
+
pattern: RegExp;
|
|
7
|
+
description: string;
|
|
8
|
+
severity: 'critical' | 'high';
|
|
9
|
+
category: 'filesystem' | 'database' | 'system';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Filesystem destructive patterns
|
|
13
|
+
*/
|
|
14
|
+
export declare const FS_DESTRUCTIVE: DestructivePattern[];
|
|
15
|
+
/**
|
|
16
|
+
* Database destructive patterns
|
|
17
|
+
*/
|
|
18
|
+
export declare const DB_DESTRUCTIVE: DestructivePattern[];
|
|
19
|
+
/**
|
|
20
|
+
* System destructive patterns
|
|
21
|
+
*/
|
|
22
|
+
export declare const SYSTEM_DESTRUCTIVE: DestructivePattern[];
|
|
23
|
+
/**
|
|
24
|
+
* All destructive patterns
|
|
25
|
+
*/
|
|
26
|
+
export declare const ALL_DESTRUCTIVE: DestructivePattern[];
|
|
27
|
+
/**
|
|
28
|
+
* Check if code contains destructive patterns
|
|
29
|
+
*/
|
|
30
|
+
export declare function detectDestructive(code: string): DestructivePattern[];
|
|
31
|
+
/**
|
|
32
|
+
* Check if specific line contains destructive command
|
|
33
|
+
*/
|
|
34
|
+
export declare function isDestructiveLine(line: string): DestructivePattern | null;
|
|
35
|
+
//# sourceMappingURL=destructive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destructive.d.ts","sourceRoot":"","sources":["../../src/rules/destructive.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,YAAY,GAAG,UAAU,GAAG,QAAQ,CAAC;CAChD;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,kBAAkB,EAyB9C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,kBAAkB,EA+B9C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAAkB,EAalD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,sBAI3B,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAUpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAOzE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destructive command detection
|
|
3
|
+
* Blocks dangerous operations: rm -rf, DROP TABLE, mass deletes, etc.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Filesystem destructive patterns
|
|
7
|
+
*/
|
|
8
|
+
export const FS_DESTRUCTIVE = [
|
|
9
|
+
{
|
|
10
|
+
pattern: /rm\s+-rf\s+[\/~]/,
|
|
11
|
+
description: 'Recursive force delete from root',
|
|
12
|
+
severity: 'critical',
|
|
13
|
+
category: 'filesystem',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
pattern: /rm\s+-rf\s+\*/,
|
|
17
|
+
description: 'Recursive force delete with wildcard',
|
|
18
|
+
severity: 'critical',
|
|
19
|
+
category: 'filesystem',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
pattern: /unlink\s*\(\s*['"]\/['"]\s*\)/,
|
|
23
|
+
description: 'Unlink root directory',
|
|
24
|
+
severity: 'critical',
|
|
25
|
+
category: 'filesystem',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
pattern: /fs\.rmdir\s*\(\s*['"]\/['"]/,
|
|
29
|
+
description: 'Remove root directory',
|
|
30
|
+
severity: 'critical',
|
|
31
|
+
category: 'filesystem',
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* Database destructive patterns
|
|
36
|
+
*/
|
|
37
|
+
export const DB_DESTRUCTIVE = [
|
|
38
|
+
{
|
|
39
|
+
pattern: /DROP\s+TABLE/i,
|
|
40
|
+
description: 'SQL DROP TABLE',
|
|
41
|
+
severity: 'critical',
|
|
42
|
+
category: 'database',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
pattern: /DROP\s+DATABASE/i,
|
|
46
|
+
description: 'SQL DROP DATABASE',
|
|
47
|
+
severity: 'critical',
|
|
48
|
+
category: 'database',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
pattern: /TRUNCATE\s+TABLE/i,
|
|
52
|
+
description: 'SQL TRUNCATE TABLE',
|
|
53
|
+
severity: 'high',
|
|
54
|
+
category: 'database',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
pattern: /DELETE\s+FROM\s+\w+\s*;/i,
|
|
58
|
+
description: 'SQL DELETE without WHERE clause',
|
|
59
|
+
severity: 'critical',
|
|
60
|
+
category: 'database',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
pattern: /db\.collection\(\w+\)\.drop\(\)/,
|
|
64
|
+
description: 'MongoDB collection drop',
|
|
65
|
+
severity: 'high',
|
|
66
|
+
category: 'database',
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
/**
|
|
70
|
+
* System destructive patterns
|
|
71
|
+
*/
|
|
72
|
+
export const SYSTEM_DESTRUCTIVE = [
|
|
73
|
+
{
|
|
74
|
+
pattern: /shutdown|reboot|halt/i,
|
|
75
|
+
description: 'System shutdown command',
|
|
76
|
+
severity: 'critical',
|
|
77
|
+
category: 'system',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
pattern: /kill\s+-9\s+1/,
|
|
81
|
+
description: 'Kill init process',
|
|
82
|
+
severity: 'critical',
|
|
83
|
+
category: 'system',
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
/**
|
|
87
|
+
* All destructive patterns
|
|
88
|
+
*/
|
|
89
|
+
export const ALL_DESTRUCTIVE = [
|
|
90
|
+
...FS_DESTRUCTIVE,
|
|
91
|
+
...DB_DESTRUCTIVE,
|
|
92
|
+
...SYSTEM_DESTRUCTIVE,
|
|
93
|
+
];
|
|
94
|
+
/**
|
|
95
|
+
* Check if code contains destructive patterns
|
|
96
|
+
*/
|
|
97
|
+
export function detectDestructive(code) {
|
|
98
|
+
const matches = [];
|
|
99
|
+
for (const pattern of ALL_DESTRUCTIVE) {
|
|
100
|
+
if (pattern.pattern.test(code)) {
|
|
101
|
+
matches.push(pattern);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return matches;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Check if specific line contains destructive command
|
|
108
|
+
*/
|
|
109
|
+
export function isDestructiveLine(line) {
|
|
110
|
+
for (const pattern of ALL_DESTRUCTIVE) {
|
|
111
|
+
if (pattern.pattern.test(line)) {
|
|
112
|
+
return pattern;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=destructive.js.map
|