@kevinrabun/judges 3.48.0 → 3.50.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/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/api-audit.d.ts +9 -0
- package/dist/commands/api-audit.d.ts.map +1 -0
- package/dist/commands/api-audit.js +360 -0
- package/dist/commands/api-audit.js.map +1 -0
- package/dist/commands/compliance-map.d.ts +9 -0
- package/dist/commands/compliance-map.d.ts.map +1 -0
- package/dist/commands/compliance-map.js +375 -0
- package/dist/commands/compliance-map.js.map +1 -0
- package/dist/commands/exec-report.d.ts +9 -0
- package/dist/commands/exec-report.d.ts.map +1 -0
- package/dist/commands/exec-report.js +272 -0
- package/dist/commands/exec-report.js.map +1 -0
- package/dist/commands/guided-tour.d.ts +9 -0
- package/dist/commands/guided-tour.d.ts.map +1 -0
- package/dist/commands/guided-tour.js +288 -0
- package/dist/commands/guided-tour.js.map +1 -0
- package/dist/commands/iac-lint.d.ts +8 -0
- package/dist/commands/iac-lint.d.ts.map +1 -0
- package/dist/commands/iac-lint.js +313 -0
- package/dist/commands/iac-lint.js.map +1 -0
- package/dist/commands/incident-response.d.ts +8 -0
- package/dist/commands/incident-response.d.ts.map +1 -0
- package/dist/commands/incident-response.js +255 -0
- package/dist/commands/incident-response.js.map +1 -0
- package/dist/commands/learning-path.d.ts +9 -0
- package/dist/commands/learning-path.d.ts.map +1 -0
- package/dist/commands/learning-path.js +326 -0
- package/dist/commands/learning-path.js.map +1 -0
- package/dist/commands/license-scan.d.ts +9 -0
- package/dist/commands/license-scan.d.ts.map +1 -0
- package/dist/commands/license-scan.js +180 -0
- package/dist/commands/license-scan.js.map +1 -0
- package/dist/commands/org-policy.d.ts +8 -0
- package/dist/commands/org-policy.d.ts.map +1 -0
- package/dist/commands/org-policy.js +208 -0
- package/dist/commands/org-policy.js.map +1 -0
- package/dist/commands/perf-compare.d.ts +9 -0
- package/dist/commands/perf-compare.d.ts.map +1 -0
- package/dist/commands/perf-compare.js +246 -0
- package/dist/commands/perf-compare.js.map +1 -0
- package/dist/commands/pii-scan.d.ts +8 -0
- package/dist/commands/pii-scan.d.ts.map +1 -0
- package/dist/commands/pii-scan.js +300 -0
- package/dist/commands/pii-scan.js.map +1 -0
- package/dist/commands/predict.d.ts +8 -0
- package/dist/commands/predict.d.ts.map +1 -0
- package/dist/commands/predict.js +219 -0
- package/dist/commands/predict.js.map +1 -0
- package/dist/commands/risk-heatmap.d.ts +8 -0
- package/dist/commands/risk-heatmap.d.ts.map +1 -0
- package/dist/commands/risk-heatmap.js +224 -0
- package/dist/commands/risk-heatmap.js.map +1 -0
- package/dist/commands/sbom-export.d.ts +8 -0
- package/dist/commands/sbom-export.d.ts.map +1 -0
- package/dist/commands/sbom-export.js +162 -0
- package/dist/commands/sbom-export.js.map +1 -0
- package/dist/commands/secret-scan.d.ts +8 -0
- package/dist/commands/secret-scan.d.ts.map +1 -0
- package/dist/commands/secret-scan.js +245 -0
- package/dist/commands/secret-scan.js.map +1 -0
- package/dist/commands/test-correlate.d.ts +8 -0
- package/dist/commands/test-correlate.d.ts.map +1 -0
- package/dist/commands/test-correlate.js +222 -0
- package/dist/commands/test-correlate.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IaC lint — dedicated linting for Dockerfiles, Kubernetes
|
|
3
|
+
* manifests, and Helm charts for security misconfigurations.
|
|
4
|
+
*
|
|
5
|
+
* All analysis local.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
8
|
+
import { join, basename } from "path";
|
|
9
|
+
// ─── Rules ──────────────────────────────────────────────────────────────────
|
|
10
|
+
const IAC_RULES = [
|
|
11
|
+
// Dockerfile rules
|
|
12
|
+
{
|
|
13
|
+
id: "dockerfile-run-as-root",
|
|
14
|
+
type: "dockerfile",
|
|
15
|
+
severity: "high",
|
|
16
|
+
check: (_content, lines) => {
|
|
17
|
+
const hasUser = lines.some((l) => /^USER\s+(?!root)/i.test(l.trim()));
|
|
18
|
+
if (!hasUser)
|
|
19
|
+
return [{ line: 1, message: "No USER directive — container runs as root" }];
|
|
20
|
+
return [];
|
|
21
|
+
},
|
|
22
|
+
recommendation: "Add USER directive with a non-root user",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "dockerfile-latest-tag",
|
|
26
|
+
type: "dockerfile",
|
|
27
|
+
severity: "medium",
|
|
28
|
+
check: (_content, lines) => {
|
|
29
|
+
const results = [];
|
|
30
|
+
for (let i = 0; i < lines.length; i++) {
|
|
31
|
+
if (/^FROM\s+\S+:latest/i.test(lines[i].trim()) ||
|
|
32
|
+
(/^FROM\s+\S+$/i.test(lines[i].trim()) && !lines[i].includes(":"))) {
|
|
33
|
+
results.push({ line: i + 1, message: "Using 'latest' or untagged base image" });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return results;
|
|
37
|
+
},
|
|
38
|
+
recommendation: "Pin base image to a specific version tag",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "dockerfile-copy-chown",
|
|
42
|
+
type: "dockerfile",
|
|
43
|
+
severity: "low",
|
|
44
|
+
check: (_content, lines) => {
|
|
45
|
+
const results = [];
|
|
46
|
+
for (let i = 0; i < lines.length; i++) {
|
|
47
|
+
if (/^COPY\s/i.test(lines[i].trim()) && !lines[i].includes("--chown")) {
|
|
48
|
+
results.push({ line: i + 1, message: "COPY without --chown — files owned by root" });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return results;
|
|
52
|
+
},
|
|
53
|
+
recommendation: "Use COPY --chown=user:group to set proper ownership",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "dockerfile-add-url",
|
|
57
|
+
type: "dockerfile",
|
|
58
|
+
severity: "high",
|
|
59
|
+
check: (_content, lines) => {
|
|
60
|
+
const results = [];
|
|
61
|
+
for (let i = 0; i < lines.length; i++) {
|
|
62
|
+
if (/^ADD\s+https?:\/\//i.test(lines[i].trim())) {
|
|
63
|
+
results.push({ line: i + 1, message: "ADD with URL — use COPY + RUN curl instead" });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return results;
|
|
67
|
+
},
|
|
68
|
+
recommendation: "Replace ADD with RUN curl/wget + COPY for better security",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: "dockerfile-env-secret",
|
|
72
|
+
type: "dockerfile",
|
|
73
|
+
severity: "critical",
|
|
74
|
+
check: (_content, lines) => {
|
|
75
|
+
const results = [];
|
|
76
|
+
for (let i = 0; i < lines.length; i++) {
|
|
77
|
+
if (/^ENV\s+.*(?:PASSWORD|SECRET|API_KEY|TOKEN)\s*=/i.test(lines[i].trim())) {
|
|
78
|
+
results.push({ line: i + 1, message: "Secret exposed in ENV directive" });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return results;
|
|
82
|
+
},
|
|
83
|
+
recommendation: "Use Docker secrets or runtime environment variables instead",
|
|
84
|
+
},
|
|
85
|
+
// Kubernetes rules
|
|
86
|
+
{
|
|
87
|
+
id: "k8s-privileged",
|
|
88
|
+
type: "kubernetes",
|
|
89
|
+
severity: "critical",
|
|
90
|
+
check: (content) => {
|
|
91
|
+
const results = [];
|
|
92
|
+
const lines = content.split("\n");
|
|
93
|
+
for (let i = 0; i < lines.length; i++) {
|
|
94
|
+
if (/privileged:\s*true/i.test(lines[i])) {
|
|
95
|
+
results.push({ line: i + 1, message: "Container running in privileged mode" });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return results;
|
|
99
|
+
},
|
|
100
|
+
recommendation: "Set privileged: false and use specific capabilities instead",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "k8s-host-network",
|
|
104
|
+
type: "kubernetes",
|
|
105
|
+
severity: "high",
|
|
106
|
+
check: (content) => {
|
|
107
|
+
const results = [];
|
|
108
|
+
const lines = content.split("\n");
|
|
109
|
+
for (let i = 0; i < lines.length; i++) {
|
|
110
|
+
if (/hostNetwork:\s*true/i.test(lines[i])) {
|
|
111
|
+
results.push({ line: i + 1, message: "Pod using host network namespace" });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return results;
|
|
115
|
+
},
|
|
116
|
+
recommendation: "Disable hostNetwork unless absolutely required",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: "k8s-no-resource-limits",
|
|
120
|
+
type: "kubernetes",
|
|
121
|
+
severity: "medium",
|
|
122
|
+
check: (content) => {
|
|
123
|
+
if (/kind:\s*(?:Deployment|Pod|StatefulSet|DaemonSet)/i.test(content) &&
|
|
124
|
+
!/resources:\s*\n\s+limits:/i.test(content)) {
|
|
125
|
+
return [{ line: 1, message: "No resource limits defined" }];
|
|
126
|
+
}
|
|
127
|
+
return [];
|
|
128
|
+
},
|
|
129
|
+
recommendation: "Add resources.limits for CPU and memory",
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "k8s-run-as-root",
|
|
133
|
+
type: "kubernetes",
|
|
134
|
+
severity: "high",
|
|
135
|
+
check: (content) => {
|
|
136
|
+
const results = [];
|
|
137
|
+
const lines = content.split("\n");
|
|
138
|
+
for (let i = 0; i < lines.length; i++) {
|
|
139
|
+
if (/runAsUser:\s*0/i.test(lines[i])) {
|
|
140
|
+
results.push({ line: i + 1, message: "Container running as root (UID 0)" });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return results;
|
|
144
|
+
},
|
|
145
|
+
recommendation: "Set runAsUser to a non-zero UID and runAsNonRoot: true",
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: "k8s-no-readiness-probe",
|
|
149
|
+
type: "kubernetes",
|
|
150
|
+
severity: "low",
|
|
151
|
+
check: (content) => {
|
|
152
|
+
if (/kind:\s*Deployment/i.test(content) && !/readinessProbe:/i.test(content)) {
|
|
153
|
+
return [{ line: 1, message: "No readiness probe configured" }];
|
|
154
|
+
}
|
|
155
|
+
return [];
|
|
156
|
+
},
|
|
157
|
+
recommendation: "Add readinessProbe for proper traffic management",
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
// ─── Scanner ────────────────────────────────────────────────────────────────
|
|
161
|
+
function detectFileType(filePath, content) {
|
|
162
|
+
const name = basename(filePath).toLowerCase();
|
|
163
|
+
if (name === "dockerfile" || name.startsWith("dockerfile."))
|
|
164
|
+
return "dockerfile";
|
|
165
|
+
if (name.endsWith(".dockerfile"))
|
|
166
|
+
return "dockerfile";
|
|
167
|
+
if (/kind:\s*(?:Deployment|Service|Pod|StatefulSet|DaemonSet|ConfigMap|Secret|Ingress)/i.test(content))
|
|
168
|
+
return "kubernetes";
|
|
169
|
+
if (/apiVersion:\s*v\d|apiVersion:\s*apps\//i.test(content))
|
|
170
|
+
return "kubernetes";
|
|
171
|
+
if (name === "chart.yaml" || name === "values.yaml")
|
|
172
|
+
return "helm";
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
function collectIacFiles(dir) {
|
|
176
|
+
const result = [];
|
|
177
|
+
const skipDirs = new Set(["node_modules", ".git", "dist", "build"]);
|
|
178
|
+
function walk(d) {
|
|
179
|
+
let entries;
|
|
180
|
+
try {
|
|
181
|
+
entries = readdirSync(d);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
for (const name of entries) {
|
|
187
|
+
if (skipDirs.has(name))
|
|
188
|
+
continue;
|
|
189
|
+
const full = join(d, name);
|
|
190
|
+
try {
|
|
191
|
+
const sub = readdirSync(full);
|
|
192
|
+
void sub;
|
|
193
|
+
walk(full);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
const lower = name.toLowerCase();
|
|
197
|
+
if (lower.includes("dockerfile") || lower.endsWith(".yaml") || lower.endsWith(".yml")) {
|
|
198
|
+
result.push(full);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
walk(dir);
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
207
|
+
export function runIacLint(argv) {
|
|
208
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
209
|
+
console.log(`
|
|
210
|
+
judges iac-lint — Lint Dockerfiles, Kubernetes manifests, and Helm charts
|
|
211
|
+
|
|
212
|
+
Usage:
|
|
213
|
+
judges iac-lint [dir]
|
|
214
|
+
judges iac-lint Dockerfile
|
|
215
|
+
judges iac-lint k8s/ --severity critical,high
|
|
216
|
+
|
|
217
|
+
Options:
|
|
218
|
+
--severity <levels> Filter by severity (comma-separated)
|
|
219
|
+
--rules List all IaC lint rules
|
|
220
|
+
--format json JSON output
|
|
221
|
+
--help, -h Show this help
|
|
222
|
+
`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
226
|
+
// List rules
|
|
227
|
+
if (argv.includes("--rules")) {
|
|
228
|
+
if (format === "json") {
|
|
229
|
+
console.log(JSON.stringify(IAC_RULES.map(({ check: _c, ...rest }) => rest), null, 2));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
console.log(`\n IaC Lint Rules (${IAC_RULES.length})\n ──────────────────────────`);
|
|
233
|
+
for (const r of IAC_RULES) {
|
|
234
|
+
console.log(` [${r.severity.toUpperCase().padEnd(8)}] ${r.id.padEnd(30)} (${r.type})`);
|
|
235
|
+
}
|
|
236
|
+
console.log("");
|
|
237
|
+
}
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const target = argv.find((a) => !a.startsWith("--") && !argv[argv.indexOf(a) - 1]?.startsWith("--")) || ".";
|
|
241
|
+
const sevFilter = argv.find((_a, i) => argv[i - 1] === "--severity");
|
|
242
|
+
// Collect files
|
|
243
|
+
let files;
|
|
244
|
+
if (existsSync(target)) {
|
|
245
|
+
try {
|
|
246
|
+
readdirSync(target);
|
|
247
|
+
files = collectIacFiles(target);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
files = [target];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
console.error(` Path not found: ${target}`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
let findings = [];
|
|
258
|
+
for (const file of files) {
|
|
259
|
+
let content;
|
|
260
|
+
try {
|
|
261
|
+
content = readFileSync(file, "utf-8");
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const fileType = detectFileType(file, content);
|
|
267
|
+
if (!fileType)
|
|
268
|
+
continue;
|
|
269
|
+
const applicableRules = IAC_RULES.filter((r) => r.type === fileType);
|
|
270
|
+
const lines = content.split("\n");
|
|
271
|
+
for (const rule of applicableRules) {
|
|
272
|
+
const matches = rule.check(content, lines);
|
|
273
|
+
for (const m of matches) {
|
|
274
|
+
findings.push({
|
|
275
|
+
file,
|
|
276
|
+
line: m.line,
|
|
277
|
+
ruleId: rule.id,
|
|
278
|
+
severity: rule.severity,
|
|
279
|
+
message: m.message,
|
|
280
|
+
recommendation: rule.recommendation,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (sevFilter) {
|
|
286
|
+
const allowed = sevFilter.split(",");
|
|
287
|
+
findings = findings.filter((f) => allowed.includes(f.severity));
|
|
288
|
+
}
|
|
289
|
+
if (format === "json") {
|
|
290
|
+
console.log(JSON.stringify({ findings, scannedFiles: files.length, timestamp: new Date().toISOString() }, null, 2));
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
console.log(`\n IaC Lint — ${files.length} files scanned`);
|
|
294
|
+
console.log(` Found: ${findings.length} issues\n ──────────────────────────`);
|
|
295
|
+
if (findings.length === 0) {
|
|
296
|
+
console.log(` ✅ No IaC issues detected\n`);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
for (const sev of ["critical", "high", "medium", "low"]) {
|
|
300
|
+
const items = findings.filter((f) => f.severity === sev);
|
|
301
|
+
if (items.length === 0)
|
|
302
|
+
continue;
|
|
303
|
+
console.log(`\n ${sev.toUpperCase()} (${items.length})`);
|
|
304
|
+
for (const f of items) {
|
|
305
|
+
console.log(` ${f.file}:${f.line} — ${f.ruleId}`);
|
|
306
|
+
console.log(` ${f.message}`);
|
|
307
|
+
console.log(` → ${f.recommendation}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
console.log("");
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=iac-lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iac-lint.js","sourceRoot":"","sources":["../../src/commands/iac-lint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incident response — generates incident response playbooks
|
|
3
|
+
* from finding spikes, CVEs, or severity escalations.
|
|
4
|
+
*
|
|
5
|
+
* All data from local files.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runIncidentResponse(argv: string[]): void;
|
|
8
|
+
//# sourceMappingURL=incident-response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incident-response.d.ts","sourceRoot":"","sources":["../../src/commands/incident-response.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoJH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoKxD"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incident response — generates incident response playbooks
|
|
3
|
+
* from finding spikes, CVEs, or severity escalations.
|
|
4
|
+
*
|
|
5
|
+
* All data from local files.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
// ─── Playbook Generation ────────────────────────────────────────────────────
|
|
10
|
+
function generatePlaybook(severity, findings) {
|
|
11
|
+
const steps = [
|
|
12
|
+
{
|
|
13
|
+
order: 1,
|
|
14
|
+
action: "Acknowledge incident and assign incident commander",
|
|
15
|
+
owner: "security-lead",
|
|
16
|
+
status: "pending",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
order: 2,
|
|
20
|
+
action: "Assess blast radius — identify all affected files and services",
|
|
21
|
+
owner: "incident-commander",
|
|
22
|
+
status: "pending",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
order: 3,
|
|
26
|
+
action: "Notify relevant code owners and stakeholders",
|
|
27
|
+
owner: "incident-commander",
|
|
28
|
+
status: "pending",
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
if (severity === "critical") {
|
|
32
|
+
steps.push({
|
|
33
|
+
order: 4,
|
|
34
|
+
action: "Evaluate if production rollback or hotfix is needed",
|
|
35
|
+
owner: "engineering-lead",
|
|
36
|
+
status: "pending",
|
|
37
|
+
}, { order: 5, action: "Apply emergency patches to critical findings", owner: "assigned-devs", status: "pending" }, { order: 6, action: "Run security regression tests on patched code", owner: "qa-lead", status: "pending" }, { order: 7, action: "Deploy hotfix through expedited release process", owner: "devops-lead", status: "pending" });
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
steps.push({
|
|
41
|
+
order: 4,
|
|
42
|
+
action: "Prioritize findings by severity and blast radius",
|
|
43
|
+
owner: "security-lead",
|
|
44
|
+
status: "pending",
|
|
45
|
+
}, { order: 5, action: "Create fix PRs for each affected file", owner: "assigned-devs", status: "pending" }, { order: 6, action: "Review and merge fixes through normal PR process", owner: "code-owners", status: "pending" });
|
|
46
|
+
}
|
|
47
|
+
const hasSqlFindings = findings.some((f) => /sql/i.test(f.ruleId) || /injection/i.test(f.title));
|
|
48
|
+
if (hasSqlFindings) {
|
|
49
|
+
steps.push({
|
|
50
|
+
order: steps.length + 1,
|
|
51
|
+
action: "Audit database access logs for exploitation evidence",
|
|
52
|
+
owner: "dba",
|
|
53
|
+
status: "pending",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const hasAuthFindings = findings.some((f) => /auth/i.test(f.ruleId) || /auth/i.test(f.title));
|
|
57
|
+
if (hasAuthFindings) {
|
|
58
|
+
steps.push({
|
|
59
|
+
order: steps.length + 1,
|
|
60
|
+
action: "Review authentication logs and rotate affected credentials",
|
|
61
|
+
owner: "security-lead",
|
|
62
|
+
status: "pending",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
steps.push({
|
|
66
|
+
order: steps.length + 1,
|
|
67
|
+
action: "Verify all findings are resolved with re-scan",
|
|
68
|
+
owner: "security-lead",
|
|
69
|
+
status: "pending",
|
|
70
|
+
}, {
|
|
71
|
+
order: steps.length + 2,
|
|
72
|
+
action: "Document lessons learned and update prevention controls",
|
|
73
|
+
owner: "incident-commander",
|
|
74
|
+
status: "pending",
|
|
75
|
+
}, {
|
|
76
|
+
order: steps.length + 3,
|
|
77
|
+
action: "Close incident and update status",
|
|
78
|
+
owner: "incident-commander",
|
|
79
|
+
status: "pending",
|
|
80
|
+
});
|
|
81
|
+
return steps;
|
|
82
|
+
}
|
|
83
|
+
function generateId() {
|
|
84
|
+
return `INC-${Date.now().toString(36).toUpperCase()}`;
|
|
85
|
+
}
|
|
86
|
+
// ─── Load findings ──────────────────────────────────────────────────────────
|
|
87
|
+
function loadRecentFindings() {
|
|
88
|
+
const paths = [".judges-findings.json", "judges-report.json"];
|
|
89
|
+
for (const p of paths) {
|
|
90
|
+
if (!existsSync(p))
|
|
91
|
+
continue;
|
|
92
|
+
try {
|
|
93
|
+
const data = JSON.parse(readFileSync(p, "utf-8"));
|
|
94
|
+
if (Array.isArray(data))
|
|
95
|
+
return data;
|
|
96
|
+
if (data.findings)
|
|
97
|
+
return data.findings;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
/* skip */
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
106
|
+
const STORE = ".judges-incidents";
|
|
107
|
+
export function runIncidentResponse(argv) {
|
|
108
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
109
|
+
console.log(`
|
|
110
|
+
judges incident-response — Incident response playbook generation
|
|
111
|
+
|
|
112
|
+
Usage:
|
|
113
|
+
judges incident-response --create --severity critical --title "SQL Injection in auth module"
|
|
114
|
+
judges incident-response --list
|
|
115
|
+
judges incident-response --show <id>
|
|
116
|
+
judges incident-response --update <id> --status investigating
|
|
117
|
+
judges incident-response --generate-from-findings
|
|
118
|
+
|
|
119
|
+
Options:
|
|
120
|
+
--create Create new incident
|
|
121
|
+
--severity <level> Incident severity (critical, high, medium)
|
|
122
|
+
--title <text> Incident title
|
|
123
|
+
--generate-from-findings Auto-generate incident from current findings
|
|
124
|
+
--list List all incidents
|
|
125
|
+
--show <id> Show incident details
|
|
126
|
+
--update <id> Update incident
|
|
127
|
+
--status <status> Set status (open, investigating, mitigating, resolved)
|
|
128
|
+
--format json JSON output
|
|
129
|
+
--help, -h Show this help
|
|
130
|
+
`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
134
|
+
if (!existsSync(STORE))
|
|
135
|
+
mkdirSync(STORE, { recursive: true });
|
|
136
|
+
const incidentsPath = join(STORE, "incidents.json");
|
|
137
|
+
const incidents = existsSync(incidentsPath) ? JSON.parse(readFileSync(incidentsPath, "utf-8")) : [];
|
|
138
|
+
// List
|
|
139
|
+
if (argv.includes("--list")) {
|
|
140
|
+
if (format === "json") {
|
|
141
|
+
console.log(JSON.stringify(incidents, null, 2));
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
console.log(`\n Incidents (${incidents.length})\n ──────────────────────────`);
|
|
145
|
+
if (incidents.length === 0) {
|
|
146
|
+
console.log(" No incidents recorded.\n");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
for (const inc of incidents) {
|
|
150
|
+
console.log(` [${inc.status.toUpperCase().padEnd(13)}] ${inc.id} ${inc.severity.toUpperCase().padEnd(8)} ${inc.title}`);
|
|
151
|
+
}
|
|
152
|
+
console.log("");
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// Show
|
|
157
|
+
const showId = argv.find((_a, i) => argv[i - 1] === "--show");
|
|
158
|
+
if (showId) {
|
|
159
|
+
const inc = incidents.find((i) => i.id === showId);
|
|
160
|
+
if (!inc) {
|
|
161
|
+
console.error(` Incident ${showId} not found.`);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (format === "json") {
|
|
165
|
+
console.log(JSON.stringify(inc, null, 2));
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
console.log(`\n Incident: ${inc.id}\n ──────────────────────────`);
|
|
169
|
+
console.log(` Title: ${inc.title}`);
|
|
170
|
+
console.log(` Severity: ${inc.severity}`);
|
|
171
|
+
console.log(` Status: ${inc.status}`);
|
|
172
|
+
console.log(` Created: ${inc.createdAt}`);
|
|
173
|
+
console.log(` Files: ${inc.affectedFiles.length}`);
|
|
174
|
+
console.log(` Findings: ${inc.findings.length}`);
|
|
175
|
+
console.log(`\n Playbook:`);
|
|
176
|
+
for (const step of inc.playbook) {
|
|
177
|
+
const icon = step.status === "done" ? "✅" : step.status === "in-progress" ? "🔄" : "⬜";
|
|
178
|
+
console.log(` ${icon} ${step.order}. ${step.action} (@${step.owner})`);
|
|
179
|
+
}
|
|
180
|
+
console.log("");
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// Update
|
|
185
|
+
const updateId = argv.find((_a, i) => argv[i - 1] === "--update");
|
|
186
|
+
if (updateId) {
|
|
187
|
+
const inc = incidents.find((i) => i.id === updateId);
|
|
188
|
+
if (!inc) {
|
|
189
|
+
console.error(` Incident ${updateId} not found.`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const newStatus = argv.find((_a, i) => argv[i - 1] === "--status");
|
|
193
|
+
if (newStatus) {
|
|
194
|
+
inc.status = newStatus;
|
|
195
|
+
inc.updatedAt = new Date().toISOString();
|
|
196
|
+
writeFileSync(incidentsPath, JSON.stringify(incidents, null, 2));
|
|
197
|
+
console.log(` Incident ${updateId} → ${newStatus}`);
|
|
198
|
+
}
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
// Generate from findings
|
|
202
|
+
if (argv.includes("--generate-from-findings")) {
|
|
203
|
+
const findings = loadRecentFindings();
|
|
204
|
+
const criticals = findings.filter((f) => f.severity === "critical");
|
|
205
|
+
const highs = findings.filter((f) => f.severity === "high");
|
|
206
|
+
if (criticals.length === 0 && highs.length === 0) {
|
|
207
|
+
console.log(" No critical or high severity findings to generate incident from.");
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const severity = criticals.length > 0 ? "critical" : "high";
|
|
211
|
+
const relevantFindings = criticals.length > 0 ? criticals : highs;
|
|
212
|
+
const affectedFiles = [...new Set(relevantFindings.map((f) => f.file || "unknown"))];
|
|
213
|
+
const incident = {
|
|
214
|
+
id: generateId(),
|
|
215
|
+
severity,
|
|
216
|
+
title: `${severity.toUpperCase()} findings detected (${relevantFindings.length})`,
|
|
217
|
+
description: `Auto-generated incident from ${relevantFindings.length} ${severity} severity findings`,
|
|
218
|
+
affectedFiles,
|
|
219
|
+
findings: relevantFindings.map((f) => ({ ruleId: f.ruleId, severity: f.severity, title: f.title })),
|
|
220
|
+
playbook: generatePlaybook(severity, relevantFindings),
|
|
221
|
+
status: "open",
|
|
222
|
+
createdAt: new Date().toISOString(),
|
|
223
|
+
updatedAt: new Date().toISOString(),
|
|
224
|
+
};
|
|
225
|
+
incidents.push(incident);
|
|
226
|
+
writeFileSync(incidentsPath, JSON.stringify(incidents, null, 2));
|
|
227
|
+
console.log(` Created incident ${incident.id} (${severity}) with ${incident.playbook.length}-step playbook`);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// Create
|
|
231
|
+
if (argv.includes("--create")) {
|
|
232
|
+
const severity = (argv.find((_a, i) => argv[i - 1] === "--severity") ||
|
|
233
|
+
"high");
|
|
234
|
+
const title = argv.find((_a, i) => argv[i - 1] === "--title") || "New security incident";
|
|
235
|
+
const findings = loadRecentFindings();
|
|
236
|
+
const incident = {
|
|
237
|
+
id: generateId(),
|
|
238
|
+
severity,
|
|
239
|
+
title,
|
|
240
|
+
description: `Manually created incident: ${title}`,
|
|
241
|
+
affectedFiles: [...new Set(findings.map((f) => f.file || "unknown"))],
|
|
242
|
+
findings: findings.map((f) => ({ ruleId: f.ruleId, severity: f.severity, title: f.title })),
|
|
243
|
+
playbook: generatePlaybook(severity, findings),
|
|
244
|
+
status: "open",
|
|
245
|
+
createdAt: new Date().toISOString(),
|
|
246
|
+
updatedAt: new Date().toISOString(),
|
|
247
|
+
};
|
|
248
|
+
incidents.push(incident);
|
|
249
|
+
writeFileSync(incidentsPath, JSON.stringify(incidents, null, 2));
|
|
250
|
+
console.log(` Created incident ${incident.id} with ${incident.playbook.length}-step playbook`);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
console.log(" Use --create, --generate-from-findings, --list, --show, or --update. Run --help for details.");
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=incident-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incident-response.js","sourceRoot":"","sources":["../../src/commands/incident-response.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning path — generates personalized developer learning
|
|
3
|
+
* modules from recurring finding patterns, tracking skill
|
|
4
|
+
* progression over time.
|
|
5
|
+
*
|
|
6
|
+
* All data stored locally.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runLearningPath(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=learning-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-path.d.ts","sourceRoot":"","sources":["../../src/commands/learning-path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgNH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4JpD"}
|