kramscan 0.1.1 → 0.2.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/README.md +392 -236
- package/dist/agent/confirmation.d.ts +5 -1
- package/dist/agent/confirmation.js +29 -9
- package/dist/agent/context.js +2 -3
- package/dist/agent/orchestrator.d.ts +2 -0
- package/dist/agent/orchestrator.js +50 -8
- package/dist/agent/prompts/system.d.ts +1 -1
- package/dist/agent/prompts/system.js +5 -7
- package/dist/agent/skills/health-check.js +22 -2
- package/dist/agent/skills/index.d.ts +1 -0
- package/dist/agent/skills/index.js +3 -1
- package/dist/agent/skills/verify-finding.d.ts +17 -0
- package/dist/agent/skills/verify-finding.js +91 -0
- package/dist/agent/skills/web-scan.js +46 -0
- package/dist/cli.js +150 -149
- package/dist/commands/agent.js +38 -38
- package/dist/commands/ai.d.ts +2 -0
- package/dist/commands/ai.js +112 -0
- package/dist/commands/analyze.js +103 -54
- package/dist/commands/config.js +55 -29
- package/dist/commands/doctor.js +20 -15
- package/dist/commands/onboard.js +188 -141
- package/dist/commands/report.js +68 -76
- package/dist/commands/scan.js +261 -81
- package/dist/commands/scans.d.ts +2 -0
- package/dist/commands/scans.js +51 -0
- package/dist/core/ai-client.d.ts +6 -1
- package/dist/core/ai-client.js +80 -12
- package/dist/core/ai-payloads.d.ts +17 -0
- package/dist/core/ai-payloads.js +54 -0
- package/dist/core/config-schema.d.ts +197 -0
- package/dist/core/config-schema.js +68 -0
- package/dist/core/config-schema.test.d.ts +1 -0
- package/dist/core/config-schema.test.js +151 -0
- package/dist/core/config.d.ts +8 -31
- package/dist/core/config.js +68 -11
- package/dist/core/errors.d.ts +71 -0
- package/dist/core/errors.js +162 -0
- package/dist/core/scan-index.d.ts +19 -0
- package/dist/core/scan-index.js +52 -0
- package/dist/core/scan-storage.d.ts +11 -0
- package/dist/core/scan-storage.js +69 -0
- package/dist/core/scanner.d.ts +95 -13
- package/dist/core/scanner.js +336 -248
- package/dist/core/vulnerability-detector.d.ts +3 -0
- package/dist/core/vulnerability-detector.js +25 -15
- package/dist/core/vulnerability-detector.test.d.ts +1 -0
- package/dist/core/vulnerability-detector.test.js +210 -0
- package/dist/index.js +3 -0
- package/dist/plugins/PluginManager.d.ts +27 -0
- package/dist/plugins/PluginManager.js +166 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.js +19 -0
- package/dist/plugins/types.d.ts +55 -0
- package/dist/plugins/types.js +25 -0
- package/dist/plugins/vulnerabilities/CSRFPlugin.d.ts +8 -0
- package/dist/plugins/vulnerabilities/CSRFPlugin.js +34 -0
- package/dist/plugins/vulnerabilities/SQLInjectionPlugin.d.ts +11 -0
- package/dist/plugins/vulnerabilities/SQLInjectionPlugin.js +109 -0
- package/dist/plugins/vulnerabilities/SecurityHeadersPlugin.d.ts +11 -0
- package/dist/plugins/vulnerabilities/SecurityHeadersPlugin.js +63 -0
- package/dist/plugins/vulnerabilities/SensitiveDataPlugin.d.ts +9 -0
- package/dist/plugins/vulnerabilities/SensitiveDataPlugin.js +32 -0
- package/dist/plugins/vulnerabilities/XSSPlugin.d.ts +15 -0
- package/dist/plugins/vulnerabilities/XSSPlugin.js +81 -0
- package/dist/reports/PdfGenerator.d.ts +36 -0
- package/dist/reports/PdfGenerator.js +379 -0
- package/dist/utils/logger.d.ts +33 -1
- package/dist/utils/logger.js +127 -8
- package/dist/utils/theme.d.ts +55 -0
- package/dist/utils/theme.js +195 -0
- package/package.json +1 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.theme = exports.CLI_VERSION = void 0;
|
|
40
|
+
exports.printBanner = printBanner;
|
|
41
|
+
exports.printInfo = printInfo;
|
|
42
|
+
exports.getSeverityColor = getSeverityColor;
|
|
43
|
+
exports.displayScanSummary = displayScanSummary;
|
|
44
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
// Read version from package.json (single source of truth)
|
|
48
|
+
function getPackageVersion() {
|
|
49
|
+
try {
|
|
50
|
+
const pkgPath = path.resolve(__dirname, "..", "..", "package.json");
|
|
51
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
52
|
+
return pkg.version || "0.0.0";
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return "0.0.0";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.CLI_VERSION = getPackageVersion();
|
|
59
|
+
exports.theme = {
|
|
60
|
+
// Colors
|
|
61
|
+
brand: chalk_1.default.hex("#00D1FF"),
|
|
62
|
+
error: chalk_1.default.red.bold,
|
|
63
|
+
success: chalk_1.default.green,
|
|
64
|
+
warning: chalk_1.default.yellow,
|
|
65
|
+
info: chalk_1.default.blue,
|
|
66
|
+
dim: chalk_1.default.gray,
|
|
67
|
+
gray: chalk_1.default.gray,
|
|
68
|
+
white: chalk_1.default.white,
|
|
69
|
+
cyan: chalk_1.default.cyan,
|
|
70
|
+
brightWhite: chalk_1.default.white.bold,
|
|
71
|
+
brightCyan: chalk_1.default.cyan.bold,
|
|
72
|
+
brightMagenta: chalk_1.default.magenta.bold,
|
|
73
|
+
brightBlue: chalk_1.default.blue.bold,
|
|
74
|
+
brightGreen: chalk_1.default.green.bold,
|
|
75
|
+
brightYellow: chalk_1.default.yellow.bold,
|
|
76
|
+
brightRed: chalk_1.default.red.bold,
|
|
77
|
+
// Severity colors
|
|
78
|
+
critical: chalk_1.default.red.bold,
|
|
79
|
+
high: chalk_1.default.red,
|
|
80
|
+
medium: chalk_1.default.yellow,
|
|
81
|
+
low: chalk_1.default.blue,
|
|
82
|
+
infoSeverity: chalk_1.default.gray,
|
|
83
|
+
yellow: chalk_1.default.yellow,
|
|
84
|
+
green: chalk_1.default.green,
|
|
85
|
+
};
|
|
86
|
+
// ─── ASCII Art Banner ──────────────────────────────────────────────
|
|
87
|
+
function printBanner() {
|
|
88
|
+
const lines = [
|
|
89
|
+
`██╗ ██╗██████╗ █████╗ ███╗ ███╗███████╗ ██████╗ █████╗ ███╗ ██╗`,
|
|
90
|
+
`██║ ██╔╝██╔══██╗██╔══██╗████╗ ████║██╔════╝██╔════╝██╔══██╗████╗ ██║`,
|
|
91
|
+
`█████╔╝ ██████╔╝███████║██╔████╔██║███████╗██║ ███████║██╔██╗ ██║`,
|
|
92
|
+
`██╔═██╗ ██╔══██╗██╔══██║██║╚██╔╝██║╚════██║██║ ██╔══██║██║╚██╗██║`,
|
|
93
|
+
`██║ ██╗██║ ██║██║ ██║██║ ╚═╝ ██║███████║╚██████╗██║ ██║██║ ╚████║`,
|
|
94
|
+
`╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝`,
|
|
95
|
+
];
|
|
96
|
+
console.log("");
|
|
97
|
+
lines.forEach((line, i) => {
|
|
98
|
+
const shade = i % 2 === 0 ? exports.theme.brightWhite : exports.theme.dim;
|
|
99
|
+
console.log(` ${shade(line)}`);
|
|
100
|
+
});
|
|
101
|
+
console.log("");
|
|
102
|
+
}
|
|
103
|
+
// ─── Dashboard Info ────────────────────────────────────────────────
|
|
104
|
+
function printInfo() {
|
|
105
|
+
console.log(` ${exports.theme.dim("───────────────────────────────────────────────────────")}`);
|
|
106
|
+
console.log(` ${exports.theme.brightWhite(" KramScan")} ${exports.theme.gray(`v${exports.CLI_VERSION}`)} ${exports.theme.dim("|")} ${exports.theme.cyan("AI-Powered Web Security Scanner")}`);
|
|
107
|
+
console.log(` ${exports.theme.dim("───────────────────────────────────────────────────────")}`);
|
|
108
|
+
console.log("");
|
|
109
|
+
console.log(` ${exports.theme.brightYellow("Tips for getting started:")}`);
|
|
110
|
+
console.log(` ${exports.theme.white("1.")} ${exports.theme.gray("Run")} ${exports.theme.cyan("kramscan onboard")} ${exports.theme.gray("to configure your API keys.")}`);
|
|
111
|
+
console.log(` ${exports.theme.white("2.")} ${exports.theme.gray("Run")} ${exports.theme.cyan("kramscan scan <url>")} ${exports.theme.gray("to scan a target.")}`);
|
|
112
|
+
console.log(` ${exports.theme.white("3.")} ${exports.theme.gray("Run")} ${exports.theme.cyan("kramscan --help")} ${exports.theme.gray("for all commands.")}`);
|
|
113
|
+
console.log("");
|
|
114
|
+
}
|
|
115
|
+
// ─── Severity Color Helper ─────────────────────────────────────────
|
|
116
|
+
function getSeverityColor(severity) {
|
|
117
|
+
const s = severity.toLowerCase();
|
|
118
|
+
if (s === "critical")
|
|
119
|
+
return exports.theme.critical;
|
|
120
|
+
if (s === "high")
|
|
121
|
+
return exports.theme.high;
|
|
122
|
+
if (s === "medium")
|
|
123
|
+
return exports.theme.medium;
|
|
124
|
+
if (s === "low")
|
|
125
|
+
return exports.theme.low;
|
|
126
|
+
return exports.theme.infoSeverity;
|
|
127
|
+
}
|
|
128
|
+
// ─── Scan Summary Display ──────────────────────────────────────────
|
|
129
|
+
function displayScanSummary(result) {
|
|
130
|
+
const { target, duration, metadata, summary, vulnerabilities, filepath, pdfPath } = result;
|
|
131
|
+
// Scan Summary
|
|
132
|
+
console.log("");
|
|
133
|
+
console.log(exports.theme.brightWhite.bold("📊 Scan Summary"));
|
|
134
|
+
console.log(exports.theme.gray("─".repeat(50)));
|
|
135
|
+
console.log("");
|
|
136
|
+
console.log(exports.theme.white("Target:"), exports.theme.cyan(target));
|
|
137
|
+
console.log(exports.theme.white("Duration:"), exports.theme.cyan(`${(duration / 1000).toFixed(2)}s`));
|
|
138
|
+
console.log(exports.theme.white("URLs Crawled:"), exports.theme.cyan(metadata.crawledUrls));
|
|
139
|
+
console.log(exports.theme.white("Forms Tested:"), exports.theme.cyan(metadata.testedForms));
|
|
140
|
+
console.log(exports.theme.white("Requests Made:"), exports.theme.cyan(metadata.requestsMade));
|
|
141
|
+
console.log("");
|
|
142
|
+
// Vulnerability summary
|
|
143
|
+
console.log(exports.theme.brightWhite.bold("🛡️ Vulnerabilities Found"));
|
|
144
|
+
console.log(exports.theme.gray("─".repeat(50)));
|
|
145
|
+
console.log("");
|
|
146
|
+
if (summary.total === 0) {
|
|
147
|
+
console.log(exports.theme.success("✓ No vulnerabilities found!"));
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
if (summary.critical > 0)
|
|
151
|
+
console.log(exports.theme.critical(` ${summary.critical} Critical`), exports.theme.gray("- Immediate action required"));
|
|
152
|
+
if (summary.high > 0)
|
|
153
|
+
console.log(exports.theme.high(` ${summary.high} High`), exports.theme.gray("- Should be fixed soon"));
|
|
154
|
+
if (summary.medium > 0)
|
|
155
|
+
console.log(exports.theme.medium(` ${summary.medium} Medium`), exports.theme.gray("- Fix when possible"));
|
|
156
|
+
if (summary.low > 0)
|
|
157
|
+
console.log(exports.theme.low(` ${summary.low} Low`), exports.theme.gray("- Minor issues"));
|
|
158
|
+
if (summary.info > 0)
|
|
159
|
+
console.log(exports.theme.infoSeverity(` ${summary.info} Info`), exports.theme.gray("- Informational"));
|
|
160
|
+
}
|
|
161
|
+
console.log("");
|
|
162
|
+
console.log(exports.theme.gray("Results saved to:"), exports.theme.white(filepath));
|
|
163
|
+
if (pdfPath) {
|
|
164
|
+
console.log(exports.theme.gray("PDF report saved to:"), exports.theme.white(pdfPath));
|
|
165
|
+
}
|
|
166
|
+
console.log("");
|
|
167
|
+
// Show top vulnerabilities
|
|
168
|
+
if (vulnerabilities.length > 0) {
|
|
169
|
+
console.log(exports.theme.brightWhite.bold("🔴 Top Findings"));
|
|
170
|
+
console.log(exports.theme.gray("─".repeat(50)));
|
|
171
|
+
console.log("");
|
|
172
|
+
const topVulns = vulnerabilities
|
|
173
|
+
.sort((a, b) => {
|
|
174
|
+
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
|
175
|
+
return severityOrder[a.severity] - severityOrder[b.severity];
|
|
176
|
+
})
|
|
177
|
+
.slice(0, 5);
|
|
178
|
+
for (const vuln of topVulns) {
|
|
179
|
+
const severityColor = getSeverityColor(vuln.severity);
|
|
180
|
+
console.log(severityColor(`[${vuln.severity.toUpperCase()}]`), exports.theme.brightWhite.bold(vuln.title));
|
|
181
|
+
console.log(exports.theme.gray(` ${vuln.url}`));
|
|
182
|
+
console.log(exports.theme.white(` ${vuln.description}`));
|
|
183
|
+
console.log("");
|
|
184
|
+
}
|
|
185
|
+
if (vulnerabilities.length > 5) {
|
|
186
|
+
console.log(exports.theme.gray(` ... and ${vulnerabilities.length - 5} more`));
|
|
187
|
+
console.log("");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
console.log(exports.theme.cyan("💡 Next steps:"));
|
|
191
|
+
console.log(exports.theme.white(` 1. Run ${exports.theme.cyan(`kramscan analyze ${filepath}`)} for AI-powered insights`));
|
|
192
|
+
console.log(exports.theme.white(" 2. PDF report is generated automatically after the scan"));
|
|
193
|
+
console.log("");
|
|
194
|
+
}
|
|
195
|
+
exports.default = exports.theme;
|