defense-mcp-server 0.9.2 → 0.9.4
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/build/core/auto-installer.js +31 -31
- package/build/core/command-allowlist.js +1 -1
- package/build/core/dependency-validator.js +9 -9
- package/build/core/distro-adapter.js +0 -7
- package/build/core/distro.js +0 -48
- package/build/core/encrypted-state.js +0 -7
- package/build/core/logger.js +1 -1
- package/build/core/pam-utils.js +1 -1
- package/build/core/parsers.js +1 -1
- package/build/core/preflight.js +13 -13
- package/build/core/progress.js +20 -20
- package/build/core/run-command.js +46 -0
- package/build/core/sudo-guard.js +4 -4
- package/build/core/third-party-installer.js +4 -4
- package/build/core/tool-wrapper.js +3 -3
- package/build/tools/access-control.js +6 -6
- package/build/tools/api-security.js +5 -51
- package/build/tools/app-hardening.js +23 -25
- package/build/tools/cloud-security.js +5 -51
- package/build/tools/compliance.js +9 -13
- package/build/tools/container-security.js +51 -52
- package/build/tools/deception.js +8 -54
- package/build/tools/dns-security.js +2 -48
- package/build/tools/encryption.js +86 -87
- package/build/tools/firewall.js +324 -30
- package/build/tools/hardening.js +12 -13
- package/build/tools/incident-response.js +3 -3
- package/build/tools/logging.js +17 -59
- package/build/tools/malware.js +2 -2
- package/build/tools/meta.js +86 -165
- package/build/tools/network-defense.js +3 -3
- package/build/tools/patch-management.js +8 -8
- package/build/tools/process-security.js +38 -92
- package/build/tools/sudo-management.js +36 -36
- package/build/tools/threat-intel.js +2 -48
- package/build/tools/vulnerability-management.js +3 -49
- package/build/tools/waf.js +47 -93
- package/build/tools/wireless-security.js +9 -55
- package/package.json +5 -3
- package/build/core/auto-installer.d.ts +0 -102
- package/build/core/auto-installer.d.ts.map +0 -1
- package/build/core/backup-manager.d.ts +0 -63
- package/build/core/backup-manager.d.ts.map +0 -1
- package/build/core/changelog.d.ts +0 -119
- package/build/core/changelog.d.ts.map +0 -1
- package/build/core/command-allowlist.d.ts +0 -129
- package/build/core/command-allowlist.d.ts.map +0 -1
- package/build/core/config.d.ts +0 -107
- package/build/core/config.d.ts.map +0 -1
- package/build/core/dependency-validator.d.ts +0 -106
- package/build/core/dependency-validator.d.ts.map +0 -1
- package/build/core/distro-adapter.d.ts +0 -177
- package/build/core/distro-adapter.d.ts.map +0 -1
- package/build/core/distro.d.ts +0 -68
- package/build/core/distro.d.ts.map +0 -1
- package/build/core/encrypted-state.d.ts +0 -76
- package/build/core/encrypted-state.d.ts.map +0 -1
- package/build/core/executor.d.ts +0 -65
- package/build/core/executor.d.ts.map +0 -1
- package/build/core/installer.d.ts +0 -129
- package/build/core/installer.d.ts.map +0 -1
- package/build/core/logger.d.ts +0 -118
- package/build/core/logger.d.ts.map +0 -1
- package/build/core/metrics.d.ts +0 -74
- package/build/core/metrics.d.ts.map +0 -1
- package/build/core/metrics.js +0 -97
- package/build/core/output-redactor.d.ts +0 -26
- package/build/core/output-redactor.d.ts.map +0 -1
- package/build/core/pam-utils.d.ts +0 -356
- package/build/core/pam-utils.d.ts.map +0 -1
- package/build/core/parsers.d.ts +0 -191
- package/build/core/parsers.d.ts.map +0 -1
- package/build/core/policy-engine.d.ts +0 -170
- package/build/core/policy-engine.d.ts.map +0 -1
- package/build/core/preflight.d.ts +0 -157
- package/build/core/preflight.d.ts.map +0 -1
- package/build/core/privilege-manager.d.ts +0 -108
- package/build/core/privilege-manager.d.ts.map +0 -1
- package/build/core/progress.d.ts +0 -99
- package/build/core/progress.d.ts.map +0 -1
- package/build/core/rate-limiter.d.ts +0 -101
- package/build/core/rate-limiter.d.ts.map +0 -1
- package/build/core/rollback.d.ts +0 -73
- package/build/core/rollback.d.ts.map +0 -1
- package/build/core/safeguards.d.ts +0 -58
- package/build/core/safeguards.d.ts.map +0 -1
- package/build/core/sanitizer.d.ts +0 -118
- package/build/core/sanitizer.d.ts.map +0 -1
- package/build/core/secure-fs.d.ts +0 -67
- package/build/core/secure-fs.d.ts.map +0 -1
- package/build/core/spawn-safe.d.ts +0 -55
- package/build/core/spawn-safe.d.ts.map +0 -1
- package/build/core/sudo-guard.d.ts +0 -167
- package/build/core/sudo-guard.d.ts.map +0 -1
- package/build/core/sudo-session.d.ts +0 -143
- package/build/core/sudo-session.d.ts.map +0 -1
- package/build/core/third-party-installer.d.ts +0 -58
- package/build/core/third-party-installer.d.ts.map +0 -1
- package/build/core/third-party-manifest.d.ts +0 -48
- package/build/core/third-party-manifest.d.ts.map +0 -1
- package/build/core/tool-annotations.d.ts +0 -13
- package/build/core/tool-annotations.d.ts.map +0 -1
- package/build/core/tool-dependencies.d.ts +0 -60
- package/build/core/tool-dependencies.d.ts.map +0 -1
- package/build/core/tool-durations.d.ts +0 -71
- package/build/core/tool-durations.d.ts.map +0 -1
- package/build/core/tool-registry.d.ts +0 -112
- package/build/core/tool-registry.d.ts.map +0 -1
- package/build/core/tool-wrapper.d.ts +0 -73
- package/build/core/tool-wrapper.d.ts.map +0 -1
- package/build/index.d.ts +0 -3
- package/build/index.d.ts.map +0 -1
- package/build/tools/access-control.d.ts +0 -11
- package/build/tools/access-control.d.ts.map +0 -1
- package/build/tools/api-security.d.ts +0 -12
- package/build/tools/api-security.d.ts.map +0 -1
- package/build/tools/app-hardening.d.ts +0 -11
- package/build/tools/app-hardening.d.ts.map +0 -1
- package/build/tools/backup.d.ts +0 -8
- package/build/tools/backup.d.ts.map +0 -1
- package/build/tools/cloud-security.d.ts +0 -17
- package/build/tools/cloud-security.d.ts.map +0 -1
- package/build/tools/compliance.d.ts +0 -11
- package/build/tools/compliance.d.ts.map +0 -1
- package/build/tools/container-security.d.ts +0 -14
- package/build/tools/container-security.d.ts.map +0 -1
- package/build/tools/deception.d.ts +0 -13
- package/build/tools/deception.d.ts.map +0 -1
- package/build/tools/dns-security.d.ts +0 -93
- package/build/tools/dns-security.d.ts.map +0 -1
- package/build/tools/ebpf-security.d.ts +0 -15
- package/build/tools/ebpf-security.d.ts.map +0 -1
- package/build/tools/encryption.d.ts +0 -12
- package/build/tools/encryption.d.ts.map +0 -1
- package/build/tools/firewall.d.ts +0 -9
- package/build/tools/firewall.d.ts.map +0 -1
- package/build/tools/hardening.d.ts +0 -8
- package/build/tools/hardening.d.ts.map +0 -1
- package/build/tools/incident-response.d.ts +0 -11
- package/build/tools/incident-response.d.ts.map +0 -1
- package/build/tools/integrity.d.ts +0 -15
- package/build/tools/integrity.d.ts.map +0 -1
- package/build/tools/logging.d.ts +0 -21
- package/build/tools/logging.d.ts.map +0 -1
- package/build/tools/malware.d.ts +0 -10
- package/build/tools/malware.d.ts.map +0 -1
- package/build/tools/meta.d.ts +0 -13
- package/build/tools/meta.d.ts.map +0 -1
- package/build/tools/network-defense.d.ts +0 -11
- package/build/tools/network-defense.d.ts.map +0 -1
- package/build/tools/patch-management.d.ts +0 -3
- package/build/tools/patch-management.d.ts.map +0 -1
- package/build/tools/process-security.d.ts +0 -12
- package/build/tools/process-security.d.ts.map +0 -1
- package/build/tools/secrets.d.ts +0 -8
- package/build/tools/secrets.d.ts.map +0 -1
- package/build/tools/sudo-management.d.ts +0 -17
- package/build/tools/sudo-management.d.ts.map +0 -1
- package/build/tools/supply-chain-security.d.ts +0 -8
- package/build/tools/supply-chain-security.d.ts.map +0 -1
- package/build/tools/threat-intel.d.ts +0 -22
- package/build/tools/threat-intel.d.ts.map +0 -1
- package/build/tools/vulnerability-management.d.ts +0 -11
- package/build/tools/vulnerability-management.d.ts.map +0 -1
- package/build/tools/waf.d.ts +0 -12
- package/build/tools/waf.d.ts.map +0 -1
- package/build/tools/wireless-security.d.ts +0 -19
- package/build/tools/wireless-security.d.ts.map +0 -1
- package/build/tools/zero-trust-network.d.ts +0 -8
- package/build/tools/zero-trust-network.d.ts.map +0 -1
|
@@ -84,7 +84,7 @@ export function registerSudoManagementTools(server) {
|
|
|
84
84
|
const status = session.getStatus();
|
|
85
85
|
return {
|
|
86
86
|
content: [
|
|
87
|
-
createTextContent(
|
|
87
|
+
createTextContent(`Already elevated as '${status.username}'.\n` +
|
|
88
88
|
`Session expires at: ${status.expiresAt ?? "never"}\n` +
|
|
89
89
|
`Remaining: ${status.remainingSeconds !== null ? `${status.remainingSeconds}s` : "∞"}\n\n` +
|
|
90
90
|
`Use sudo_session action=drop to end the current session before re-elevating.`),
|
|
@@ -100,7 +100,7 @@ export function registerSudoManagementTools(server) {
|
|
|
100
100
|
: "unknown";
|
|
101
101
|
return {
|
|
102
102
|
content: [
|
|
103
|
-
createErrorContent(
|
|
103
|
+
createErrorContent(`Authentication rate limit exceeded.\n\n` +
|
|
104
104
|
`Too many failed attempts were detected within the last 5 minutes.\n` +
|
|
105
105
|
`Please wait until ${resetAt} before trying again.\n\n` +
|
|
106
106
|
`For security, this lockout cannot be bypassed.\n` +
|
|
@@ -120,7 +120,7 @@ export function registerSudoManagementTools(server) {
|
|
|
120
120
|
invalidatePreflightCaches();
|
|
121
121
|
const status = session.getStatus();
|
|
122
122
|
const lines = [
|
|
123
|
-
|
|
123
|
+
`Privileges elevated successfully!`,
|
|
124
124
|
``,
|
|
125
125
|
` User: ${status.username}`,
|
|
126
126
|
` Expires: ${status.expiresAt ?? "never (running as root)"}`,
|
|
@@ -142,7 +142,7 @@ export function registerSudoManagementTools(server) {
|
|
|
142
142
|
: "unknown";
|
|
143
143
|
return {
|
|
144
144
|
content: [
|
|
145
|
-
createErrorContent(
|
|
145
|
+
createErrorContent(`Authentication rate limit exceeded.\n\n` +
|
|
146
146
|
`Too many failed attempts. Please wait until ${resetAt} before retrying.\n\n` +
|
|
147
147
|
`For security, this lockout cannot be bypassed.`),
|
|
148
148
|
],
|
|
@@ -160,7 +160,7 @@ export function registerSudoManagementTools(server) {
|
|
|
160
160
|
: "";
|
|
161
161
|
return {
|
|
162
162
|
content: [
|
|
163
|
-
createErrorContent(
|
|
163
|
+
createErrorContent(`Authentication failed: ${result.error}\n\n` +
|
|
164
164
|
`${attemptsLine}\n\n` +
|
|
165
165
|
`Please verify:\n` +
|
|
166
166
|
` 1. The password is correct\n` +
|
|
@@ -197,7 +197,7 @@ export function registerSudoManagementTools(server) {
|
|
|
197
197
|
const status = session.getStatus();
|
|
198
198
|
return {
|
|
199
199
|
content: [
|
|
200
|
-
createTextContent(
|
|
200
|
+
createTextContent(`Already elevated as '${status.username}'.\n` +
|
|
201
201
|
`Session expires at: ${status.expiresAt ?? "never"}\n` +
|
|
202
202
|
`Remaining: ${status.remainingSeconds !== null ? `${status.remainingSeconds}s` : "∞"}\n\n` +
|
|
203
203
|
`Use sudo_session action=drop to end the current session before re-elevating.`),
|
|
@@ -212,7 +212,7 @@ export function registerSudoManagementTools(server) {
|
|
|
212
212
|
: "unknown";
|
|
213
213
|
return {
|
|
214
214
|
content: [
|
|
215
|
-
createErrorContent(
|
|
215
|
+
createErrorContent(`Authentication rate limit exceeded.\n\n` +
|
|
216
216
|
`Too many failed attempts. Please wait until ${resetAt} before retrying.`),
|
|
217
217
|
],
|
|
218
218
|
isError: true,
|
|
@@ -226,7 +226,7 @@ export function registerSudoManagementTools(server) {
|
|
|
226
226
|
if (!hasDisplay) {
|
|
227
227
|
return {
|
|
228
228
|
content: [
|
|
229
|
-
createErrorContent(
|
|
229
|
+
createErrorContent(`GUI elevation is not available — no graphical session detected.\n\n` +
|
|
230
230
|
`Could not find DISPLAY or WAYLAND_DISPLAY in the current process\n` +
|
|
231
231
|
`or any desktop session process (gnome-shell, plasmashell, etc.).\n\n` +
|
|
232
232
|
`Use sudo_session action=elevate with your password instead.`),
|
|
@@ -239,7 +239,7 @@ export function registerSudoManagementTools(server) {
|
|
|
239
239
|
if (!guiTool) {
|
|
240
240
|
return {
|
|
241
241
|
content: [
|
|
242
|
-
createErrorContent(
|
|
242
|
+
createErrorContent(`No GUI password dialog tool found.\n\n` +
|
|
243
243
|
`Install one of: zenity, kdialog, or ssh-askpass\n` +
|
|
244
244
|
` sudo apt install zenity # GNOME/GTK\n` +
|
|
245
245
|
` sudo apt install kdialog # KDE/Qt\n\n` +
|
|
@@ -257,7 +257,7 @@ export function registerSudoManagementTools(server) {
|
|
|
257
257
|
if (!password) {
|
|
258
258
|
return {
|
|
259
259
|
content: [
|
|
260
|
-
createErrorContent(
|
|
260
|
+
createErrorContent(`Password dialog was cancelled or timed out.\n\n` +
|
|
261
261
|
`No password was entered. Try again with:\n` +
|
|
262
262
|
` sudo_session action=elevate_gui\n\n` +
|
|
263
263
|
`Or provide your password directly with:\n` +
|
|
@@ -278,7 +278,7 @@ export function registerSudoManagementTools(server) {
|
|
|
278
278
|
const status = session.getStatus();
|
|
279
279
|
return {
|
|
280
280
|
content: [
|
|
281
|
-
createTextContent(
|
|
281
|
+
createTextContent(`Privileges elevated successfully!\n\n` +
|
|
282
282
|
` User: ${status.username}\n` +
|
|
283
283
|
` Expires: ${status.expiresAt ?? "never (running as root)"}\n` +
|
|
284
284
|
` Timeout: ${timeout_minutes} minutes\n` +
|
|
@@ -295,7 +295,7 @@ export function registerSudoManagementTools(server) {
|
|
|
295
295
|
: `Attempts remaining before lockout: ${rlAfter.attemptsRemaining}`;
|
|
296
296
|
return {
|
|
297
297
|
content: [
|
|
298
|
-
createErrorContent(
|
|
298
|
+
createErrorContent(`Authentication failed: ${result.error}\n\n` +
|
|
299
299
|
`${attemptsLine}\n\n` +
|
|
300
300
|
`The password was securely wiped. Please try again.`),
|
|
301
301
|
],
|
|
@@ -319,7 +319,7 @@ export function registerSudoManagementTools(server) {
|
|
|
319
319
|
if (!status.elevated) {
|
|
320
320
|
const rlLines = [];
|
|
321
321
|
if (rl.limited) {
|
|
322
|
-
rlLines.push(`
|
|
322
|
+
rlLines.push(` WARNING: Rate limit ACTIVE — elevation blocked`);
|
|
323
323
|
rlLines.push(` Unlocks at: ${rl.resetAt ? new Date(rl.resetAt).toLocaleTimeString() : "unknown"}`);
|
|
324
324
|
}
|
|
325
325
|
else {
|
|
@@ -327,7 +327,7 @@ export function registerSudoManagementTools(server) {
|
|
|
327
327
|
}
|
|
328
328
|
return {
|
|
329
329
|
content: [
|
|
330
|
-
createTextContent(
|
|
330
|
+
createTextContent(`Not elevated — sudo credentials are not cached.\n\n` +
|
|
331
331
|
rlLines.join("\n") + "\n\n" +
|
|
332
332
|
`Use sudo_session action=elevate to provide your password and enable\n` +
|
|
333
333
|
`transparent sudo for all defensive security tools.`),
|
|
@@ -335,8 +335,8 @@ export function registerSudoManagementTools(server) {
|
|
|
335
335
|
};
|
|
336
336
|
}
|
|
337
337
|
const sections = [];
|
|
338
|
-
sections.push("
|
|
339
|
-
sections.push("
|
|
338
|
+
sections.push("Sudo Session Active");
|
|
339
|
+
sections.push("");
|
|
340
340
|
sections.push(` User: ${status.username}`);
|
|
341
341
|
sections.push(` Expires: ${status.expiresAt ?? "never (root)"}`);
|
|
342
342
|
sections.push(` Auth method: password (sudo -S)`);
|
|
@@ -345,7 +345,7 @@ export function registerSudoManagementTools(server) {
|
|
|
345
345
|
const secs = status.remainingSeconds % 60;
|
|
346
346
|
sections.push(` Remaining: ${mins}m ${secs}s`);
|
|
347
347
|
if (status.remainingSeconds < 120) {
|
|
348
|
-
sections.push(`\n
|
|
348
|
+
sections.push(`\n Session expiring soon! Use sudo_session action=extend to continue.`);
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
351
|
else {
|
|
@@ -374,7 +374,7 @@ export function registerSudoManagementTools(server) {
|
|
|
374
374
|
if (wasElevated) {
|
|
375
375
|
return {
|
|
376
376
|
content: [
|
|
377
|
-
createTextContent(
|
|
377
|
+
createTextContent(`Privileges dropped successfully.\n\n` +
|
|
378
378
|
` Previous user: ${prevStatus.username}\n` +
|
|
379
379
|
` Password buffer: zeroed\n` +
|
|
380
380
|
` System sudo cache: invalidated\n\n` +
|
|
@@ -384,7 +384,7 @@ export function registerSudoManagementTools(server) {
|
|
|
384
384
|
}
|
|
385
385
|
return {
|
|
386
386
|
content: [
|
|
387
|
-
createTextContent(
|
|
387
|
+
createTextContent(`No active sudo session to drop.\n` +
|
|
388
388
|
`The system is already in an unprivileged state.`),
|
|
389
389
|
],
|
|
390
390
|
};
|
|
@@ -405,7 +405,7 @@ export function registerSudoManagementTools(server) {
|
|
|
405
405
|
if (!session.isElevated()) {
|
|
406
406
|
return {
|
|
407
407
|
content: [
|
|
408
|
-
createErrorContent(
|
|
408
|
+
createErrorContent(`No active sudo session to extend.\n\n` +
|
|
409
409
|
`Use sudo_session action=elevate to provide your password and start a session first.`),
|
|
410
410
|
],
|
|
411
411
|
isError: true,
|
|
@@ -428,7 +428,7 @@ export function registerSudoManagementTools(server) {
|
|
|
428
428
|
const status = session.getStatus();
|
|
429
429
|
return {
|
|
430
430
|
content: [
|
|
431
|
-
createTextContent(
|
|
431
|
+
createTextContent(`Session extended by ${minutes} minutes.\n\n` +
|
|
432
432
|
` User: ${status.username}\n` +
|
|
433
433
|
` New expiry: ${status.expiresAt ?? "never (root)"}\n` +
|
|
434
434
|
` Remaining: ${status.remainingSeconds !== null ? `${Math.floor(status.remainingSeconds / 60)}m ${status.remainingSeconds % 60}s` : "∞"}`),
|
|
@@ -501,26 +501,26 @@ export function registerSudoManagementTools(server) {
|
|
|
501
501
|
const otherFails = results.filter((r) => !r.ready && !r.needsSudo && r.missingDeps.length === 0);
|
|
502
502
|
// Build report
|
|
503
503
|
const lines = [];
|
|
504
|
-
lines.push("
|
|
505
|
-
lines.push("
|
|
504
|
+
lines.push("Pre-flight Batch Check Results");
|
|
505
|
+
lines.push("");
|
|
506
506
|
lines.push(`Checked: ${toolNames.length} tools`);
|
|
507
|
-
lines.push(`
|
|
508
|
-
lines.push(`
|
|
509
|
-
lines.push(`
|
|
507
|
+
lines.push(` Ready: ${ready.length}`);
|
|
508
|
+
lines.push(` Need sudo: ${needSudo.length}`);
|
|
509
|
+
lines.push(` Missing deps: ${needDeps.length}`);
|
|
510
510
|
if (otherFails.length > 0) {
|
|
511
|
-
lines.push(`
|
|
511
|
+
lines.push(` Other issues: ${otherFails.length}`);
|
|
512
512
|
}
|
|
513
513
|
// Section: Tools that need sudo elevation
|
|
514
514
|
if (needSudo.length > 0) {
|
|
515
515
|
lines.push("");
|
|
516
|
-
lines.push("
|
|
517
|
-
lines.push("
|
|
516
|
+
lines.push("SUDO ELEVATION REQUIRED");
|
|
517
|
+
lines.push("");
|
|
518
518
|
lines.push("The following tools need sudo privileges.");
|
|
519
519
|
lines.push("Call sudo_session action=elevate with the user's password BEFORE");
|
|
520
520
|
lines.push("executing any of these tools:");
|
|
521
521
|
lines.push("");
|
|
522
522
|
for (const r of needSudo) {
|
|
523
|
-
lines.push(`
|
|
523
|
+
lines.push(` ${r.tool}`);
|
|
524
524
|
if (r.sudoReason) {
|
|
525
525
|
lines.push(` Reason: ${r.sudoReason}`);
|
|
526
526
|
}
|
|
@@ -532,10 +532,10 @@ export function registerSudoManagementTools(server) {
|
|
|
532
532
|
// Section: Missing dependencies
|
|
533
533
|
if (needDeps.length > 0) {
|
|
534
534
|
lines.push("");
|
|
535
|
-
lines.push("
|
|
536
|
-
lines.push("
|
|
535
|
+
lines.push("MISSING DEPENDENCIES");
|
|
536
|
+
lines.push("");
|
|
537
537
|
for (const r of needDeps) {
|
|
538
|
-
lines.push(`
|
|
538
|
+
lines.push(` ${r.tool}`);
|
|
539
539
|
for (const dep of r.missingDeps) {
|
|
540
540
|
lines.push(` Missing: ${dep}`);
|
|
541
541
|
}
|
|
@@ -547,10 +547,10 @@ export function registerSudoManagementTools(server) {
|
|
|
547
547
|
// Section: Ready tools
|
|
548
548
|
if (ready.length > 0) {
|
|
549
549
|
lines.push("");
|
|
550
|
-
lines.push("
|
|
551
|
-
lines.push("
|
|
550
|
+
lines.push("READY TO EXECUTE");
|
|
551
|
+
lines.push("");
|
|
552
552
|
for (const r of ready) {
|
|
553
|
-
lines.push(`
|
|
553
|
+
lines.push(` ${r.tool}`);
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
556
|
// Build machine-readable metadata
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* feeds, feed management, and blocklist application to iptables/fail2ban/hosts.
|
|
9
9
|
*/
|
|
10
10
|
import { z } from "zod";
|
|
11
|
-
import {
|
|
11
|
+
import { runCommand } from "../core/run-command.js";
|
|
12
12
|
import { createTextContent, createErrorContent, formatToolOutput, } from "../core/parsers.js";
|
|
13
13
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
14
14
|
// ── Constants ──────────────────────────────────────────────────────────────────
|
|
@@ -26,53 +26,7 @@ const MAX_BATCH_SIZE = 1000;
|
|
|
26
26
|
const SINKHOLE_IPS = new Set(["0.0.0.0", "127.0.0.1"]);
|
|
27
27
|
/** Basic IPv4 regex for validation */
|
|
28
28
|
const IPV4_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
29
|
-
|
|
30
|
-
* Run a command via spawnSafe and collect output as a promise.
|
|
31
|
-
* Handles errors gracefully — returns error info instead of throwing.
|
|
32
|
-
*/
|
|
33
|
-
async function runCommand(command, args, timeoutMs = 30_000) {
|
|
34
|
-
return new Promise((resolve) => {
|
|
35
|
-
let child;
|
|
36
|
-
try {
|
|
37
|
-
child = spawnSafe(command, args);
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
41
|
-
resolve({ stdout: "", stderr: msg, exitCode: -1 });
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
let stdout = "";
|
|
45
|
-
let stderr = "";
|
|
46
|
-
let resolved = false;
|
|
47
|
-
const timer = setTimeout(() => {
|
|
48
|
-
if (!resolved) {
|
|
49
|
-
resolved = true;
|
|
50
|
-
child.kill("SIGTERM");
|
|
51
|
-
resolve({ stdout, stderr: stderr + "\n[TIMEOUT]", exitCode: -1 });
|
|
52
|
-
}
|
|
53
|
-
}, timeoutMs);
|
|
54
|
-
child.stdout?.on("data", (data) => {
|
|
55
|
-
stdout += data.toString();
|
|
56
|
-
});
|
|
57
|
-
child.stderr?.on("data", (data) => {
|
|
58
|
-
stderr += data.toString();
|
|
59
|
-
});
|
|
60
|
-
child.on("close", (code) => {
|
|
61
|
-
if (!resolved) {
|
|
62
|
-
resolved = true;
|
|
63
|
-
clearTimeout(timer);
|
|
64
|
-
resolve({ stdout, stderr, exitCode: code ?? -1 });
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
child.on("error", (err) => {
|
|
68
|
-
if (!resolved) {
|
|
69
|
-
resolved = true;
|
|
70
|
-
clearTimeout(timer);
|
|
71
|
-
resolve({ stdout, stderr: err.message, exitCode: -1 });
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
29
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
76
30
|
// ── Validation ─────────────────────────────────────────────────────────────────
|
|
77
31
|
/**
|
|
78
32
|
* Validate an IPv4 address.
|
|
@@ -7,59 +7,13 @@
|
|
|
7
7
|
* using nmap, nikto, and searchsploit.
|
|
8
8
|
*/
|
|
9
9
|
import { z } from "zod";
|
|
10
|
-
import {
|
|
10
|
+
import { runCommand } from "../core/run-command.js";
|
|
11
11
|
import { secureWriteFileSync } from "../core/secure-fs.js";
|
|
12
12
|
import { createTextContent, createErrorContent, formatToolOutput, } from "../core/parsers.js";
|
|
13
13
|
import { existsSync, readFileSync } from "node:fs";
|
|
14
14
|
// ── Constants ──────────────────────────────────────────────────────────────────
|
|
15
15
|
const VULN_TRACKER_PATH = "/var/lib/defense-mcp/vuln-tracker.json";
|
|
16
|
-
|
|
17
|
-
* Run a command via spawnSafe and collect output as a promise.
|
|
18
|
-
* Handles errors gracefully — returns error info instead of throwing.
|
|
19
|
-
*/
|
|
20
|
-
async function runCommand(command, args, timeoutMs = 60_000) {
|
|
21
|
-
return new Promise((resolve) => {
|
|
22
|
-
let child;
|
|
23
|
-
try {
|
|
24
|
-
child = spawnSafe(command, args);
|
|
25
|
-
}
|
|
26
|
-
catch (err) {
|
|
27
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
28
|
-
resolve({ stdout: "", stderr: msg, exitCode: -1 });
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
let stdout = "";
|
|
32
|
-
let stderr = "";
|
|
33
|
-
let resolved = false;
|
|
34
|
-
const timer = setTimeout(() => {
|
|
35
|
-
if (!resolved) {
|
|
36
|
-
resolved = true;
|
|
37
|
-
child.kill("SIGTERM");
|
|
38
|
-
resolve({ stdout, stderr: stderr + "\n[TIMEOUT]", exitCode: -1 });
|
|
39
|
-
}
|
|
40
|
-
}, timeoutMs);
|
|
41
|
-
child.stdout?.on("data", (data) => {
|
|
42
|
-
stdout += data.toString();
|
|
43
|
-
});
|
|
44
|
-
child.stderr?.on("data", (data) => {
|
|
45
|
-
stderr += data.toString();
|
|
46
|
-
});
|
|
47
|
-
child.on("close", (code) => {
|
|
48
|
-
if (!resolved) {
|
|
49
|
-
resolved = true;
|
|
50
|
-
clearTimeout(timer);
|
|
51
|
-
resolve({ stdout, stderr, exitCode: code ?? -1 });
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
child.on("error", (err) => {
|
|
55
|
-
if (!resolved) {
|
|
56
|
-
resolved = true;
|
|
57
|
-
clearTimeout(timer);
|
|
58
|
-
resolve({ stdout, stderr: err.message, exitCode: -1 });
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}
|
|
16
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
63
17
|
/**
|
|
64
18
|
* Load the vulnerability tracker database from disk.
|
|
65
19
|
*/
|
|
@@ -551,7 +505,7 @@ export function registerVulnerabilityManagementTools(server) {
|
|
|
551
505
|
.map((v, i) => `${i + 1}. [${v.severity.toUpperCase()}] ${v.vuln_id} (score: ${v.priority_score})\n` +
|
|
552
506
|
` ${v.description}\n` +
|
|
553
507
|
` Action: ${v.recommended_action}` +
|
|
554
|
-
(v.exploit_available ? "\n
|
|
508
|
+
(v.exploit_available ? "\n WARNING: EXPLOIT AVAILABLE" : ""))
|
|
555
509
|
.join("\n\n"))],
|
|
556
510
|
};
|
|
557
511
|
}
|