defense-mcp-server 0.9.2 → 0.9.3

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.
Files changed (69) hide show
  1. package/build/core/auto-installer.js +31 -31
  2. package/build/core/command-allowlist.js +1 -1
  3. package/build/core/dependency-validator.js +9 -9
  4. package/build/core/distro-adapter.d.ts +0 -5
  5. package/build/core/distro-adapter.d.ts.map +1 -1
  6. package/build/core/distro-adapter.js +0 -7
  7. package/build/core/distro.d.ts +0 -11
  8. package/build/core/distro.d.ts.map +1 -1
  9. package/build/core/distro.js +0 -48
  10. package/build/core/encrypted-state.d.ts +0 -7
  11. package/build/core/encrypted-state.d.ts.map +1 -1
  12. package/build/core/encrypted-state.js +0 -7
  13. package/build/core/logger.js +1 -1
  14. package/build/core/pam-utils.js +1 -1
  15. package/build/core/parsers.js +1 -1
  16. package/build/core/preflight.d.ts +4 -4
  17. package/build/core/preflight.js +13 -13
  18. package/build/core/progress.js +20 -20
  19. package/build/core/run-command.d.ts +14 -0
  20. package/build/core/run-command.d.ts.map +1 -0
  21. package/build/core/run-command.js +46 -0
  22. package/build/core/spawn-safe.d.ts +6 -6
  23. package/build/core/spawn-safe.d.ts.map +1 -1
  24. package/build/core/sudo-guard.js +4 -4
  25. package/build/core/third-party-installer.js +4 -4
  26. package/build/core/tool-wrapper.js +3 -3
  27. package/build/tools/access-control.js +6 -6
  28. package/build/tools/api-security.d.ts.map +1 -1
  29. package/build/tools/api-security.js +5 -51
  30. package/build/tools/app-hardening.d.ts.map +1 -1
  31. package/build/tools/app-hardening.js +23 -25
  32. package/build/tools/cloud-security.d.ts.map +1 -1
  33. package/build/tools/cloud-security.js +5 -51
  34. package/build/tools/compliance.d.ts.map +1 -1
  35. package/build/tools/compliance.js +9 -13
  36. package/build/tools/container-security.d.ts.map +1 -1
  37. package/build/tools/container-security.js +51 -52
  38. package/build/tools/deception.d.ts.map +1 -1
  39. package/build/tools/deception.js +8 -54
  40. package/build/tools/dns-security.d.ts.map +1 -1
  41. package/build/tools/dns-security.js +2 -48
  42. package/build/tools/encryption.d.ts.map +1 -1
  43. package/build/tools/encryption.js +86 -87
  44. package/build/tools/firewall.d.ts.map +1 -1
  45. package/build/tools/firewall.js +324 -30
  46. package/build/tools/hardening.d.ts.map +1 -1
  47. package/build/tools/hardening.js +12 -13
  48. package/build/tools/incident-response.d.ts.map +1 -1
  49. package/build/tools/incident-response.js +3 -3
  50. package/build/tools/logging.d.ts.map +1 -1
  51. package/build/tools/logging.js +17 -59
  52. package/build/tools/malware.js +2 -2
  53. package/build/tools/meta.d.ts.map +1 -1
  54. package/build/tools/meta.js +86 -165
  55. package/build/tools/network-defense.d.ts.map +1 -1
  56. package/build/tools/network-defense.js +3 -3
  57. package/build/tools/patch-management.js +8 -8
  58. package/build/tools/process-security.d.ts.map +1 -1
  59. package/build/tools/process-security.js +38 -92
  60. package/build/tools/sudo-management.js +36 -36
  61. package/build/tools/threat-intel.d.ts.map +1 -1
  62. package/build/tools/threat-intel.js +2 -48
  63. package/build/tools/vulnerability-management.d.ts.map +1 -1
  64. package/build/tools/vulnerability-management.js +3 -49
  65. package/build/tools/waf.d.ts.map +1 -1
  66. package/build/tools/waf.js +47 -93
  67. package/build/tools/wireless-security.d.ts.map +1 -1
  68. package/build/tools/wireless-security.js +9 -55
  69. package/package.json +4 -2
@@ -19,7 +19,7 @@ import { logChange, createChangeEntry, backupFile } from "../core/changelog.js";
19
19
  import { sanitizeArgs, validateAuditdKey, validateTarget, validateToolPath, } from "../core/sanitizer.js";
20
20
  import { getDistroAdapter } from "../core/distro-adapter.js";
21
21
  import { existsSync } from "node:fs";
22
- import { spawnSafe } from "../core/spawn-safe.js";
22
+ import { runCommand } from "../core/run-command.js";
23
23
  // ── TOOL-015 remediation: allowed directories for log file paths ────────────
24
24
  const ALLOWED_LOG_DIRS = ["/var/log", "/var/spool", "/tmp", "/var/lib", "/run/log"];
25
25
  // ── SIEM constants ──────────────────────────────────────────────────────────
@@ -34,49 +34,7 @@ const LOG_SOURCE_FILES = {
34
34
  };
35
35
  /** Hostname/IP validation pattern */
36
36
  const SIEM_HOST_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,253}[a-zA-Z0-9]$/;
37
- async function runCommand(command, args, timeoutMs = 30_000) {
38
- return new Promise((resolve) => {
39
- let child;
40
- try {
41
- child = spawnSafe(command, args);
42
- }
43
- catch (err) {
44
- const msg = err instanceof Error ? err.message : String(err);
45
- resolve({ stdout: "", stderr: msg, exitCode: -1 });
46
- return;
47
- }
48
- let stdout = "";
49
- let stderr = "";
50
- let resolved = false;
51
- const timer = setTimeout(() => {
52
- if (!resolved) {
53
- resolved = true;
54
- child.kill("SIGTERM");
55
- resolve({ stdout, stderr: stderr + "\n[TIMEOUT]", exitCode: -1 });
56
- }
57
- }, timeoutMs);
58
- child.stdout?.on("data", (data) => {
59
- stdout += data.toString();
60
- });
61
- child.stderr?.on("data", (data) => {
62
- stderr += data.toString();
63
- });
64
- child.on("close", (code) => {
65
- if (!resolved) {
66
- resolved = true;
67
- clearTimeout(timer);
68
- resolve({ stdout, stderr, exitCode: code ?? -1 });
69
- }
70
- });
71
- child.on("error", (err) => {
72
- if (!resolved) {
73
- resolved = true;
74
- clearTimeout(timer);
75
- resolve({ stdout, stderr: err.message, exitCode: -1 });
76
- }
77
- });
78
- });
79
- }
37
+ // ── SIEM helpers ────────────────────────────────────────────────────────────
80
38
  /**
81
39
  * Validate a SIEM host string (hostname or IP address).
82
40
  * Returns true if the host looks reasonable.
@@ -757,7 +715,7 @@ export function registerLoggingTools(server) {
757
715
  const result = await executeCommand({ command: "sudo", args, toolName: "log_management", timeout: getToolTimeout("auditd") });
758
716
  if (result.exitCode !== 0)
759
717
  return { content: [createErrorContent(`aureport failed (exit ${result.exitCode}): ${result.stderr}`)], isError: true };
760
- return { content: [createTextContent(`Audit Report (${report_type}):\n${"=".repeat(50)}\n${result.stdout}`)] };
718
+ return { content: [createTextContent(`Audit Report (${report_type}):\n${result.stdout}`)] };
761
719
  }
762
720
  catch (err) {
763
721
  return { content: [createErrorContent(err instanceof Error ? err.message : String(err))], isError: true };
@@ -809,7 +767,7 @@ export function registerLoggingTools(server) {
809
767
  return { description: r.description, rule: r.rule, present: found };
810
768
  });
811
769
  const present = results.filter(r => r.present).length;
812
- return { content: [createTextContent(JSON.stringify({ summary: { totalRequired: CIS_RULES.length, present, missing: CIS_RULES.length - present, compliancePercent: Math.round((present / CIS_RULES.length) * 100) }, results }, null, 2))] };
770
+ return { content: [createTextContent(JSON.stringify({ summary: { totalRequired: CIS_RULES.length, present, missing: CIS_RULES.length - present, compliancePercent: Math.round((present / CIS_RULES.length) * 100) }, results }))] };
813
771
  }
814
772
  catch (error) {
815
773
  return { content: [createErrorContent(error instanceof Error ? error.message : String(error))], isError: true };
@@ -930,7 +888,7 @@ export function registerLoggingTools(server) {
930
888
  try {
931
889
  const statusResult = await executeCommand({ command: "sudo", args: ["fail2ban-client", "status"], timeout: 10000, toolName: "log_management" });
932
890
  if (statusResult.exitCode !== 0) {
933
- return { content: [createTextContent(JSON.stringify({ installed: false, recommendation: "Install fail2ban: sudo apt install fail2ban && sudo systemctl enable fail2ban" }, null, 2))] };
891
+ return { content: [createTextContent(JSON.stringify({ installed: false, recommendation: "Install fail2ban: sudo apt install fail2ban && sudo systemctl enable fail2ban" }))] };
934
892
  }
935
893
  const jailLine = statusResult.stdout.match(/Jail list:\s*(.*)/);
936
894
  const jails = jailLine ? jailLine[1].split(",").map(j => j.trim()).filter(Boolean) : [];
@@ -948,7 +906,7 @@ export function registerLoggingTools(server) {
948
906
  }
949
907
  const recommendedJails = ["sshd", "apache-auth", "nginx-http-auth", "postfix"];
950
908
  const missingJails = recommendedJails.filter(j => !jails.includes(j));
951
- return { content: [createTextContent(JSON.stringify({ installed: true, activeJails: jails.length, jails, missingRecommended: missingJails, findings, summary: { pass: findings.filter(f => f.status === "PASS").length, warn: findings.filter(f => f.status === "WARN").length } }, null, 2))] };
909
+ return { content: [createTextContent(JSON.stringify({ installed: true, activeJails: jails.length, jails, missingRecommended: missingJails, findings, summary: { pass: findings.filter(f => f.status === "PASS").length, warn: findings.filter(f => f.status === "WARN").length } }))] };
952
910
  }
953
911
  catch (error) {
954
912
  return { content: [createErrorContent(error instanceof Error ? error.message : String(error))], isError: true };
@@ -1021,7 +979,7 @@ export function registerLoggingTools(server) {
1021
979
  const logPerms = await executeCommand({ command: "stat", args: ["-c", "%a %U:%G", "/var/log"], timeout: 5000, toolName: "log_management" });
1022
980
  findings.push({ check: "var_log_permissions", status: logPerms.stdout.trim().startsWith("755") || logPerms.stdout.trim().startsWith("750") ? "PASS" : "WARN", value: logPerms.stdout.trim(), description: "/var/log directory permissions" });
1023
981
  const passCount = findings.filter(f => f.status === "PASS").length;
1024
- return { content: [createTextContent(JSON.stringify({ summary: { total: findings.length, pass: passCount, fail: findings.filter(f => f.status === "FAIL").length, warn: findings.filter(f => f.status === "WARN").length }, findings }, null, 2))] };
982
+ return { content: [createTextContent(JSON.stringify({ summary: { total: findings.length, pass: passCount, fail: findings.filter(f => f.status === "FAIL").length, warn: findings.filter(f => f.status === "WARN").length }, findings }))] };
1025
983
  }
1026
984
  catch (error) {
1027
985
  return { content: [createErrorContent(error instanceof Error ? error.message : String(error))], isError: true };
@@ -1193,7 +1151,7 @@ export function registerLoggingTools(server) {
1193
1151
  }
1194
1152
  else {
1195
1153
  text += `Version: ${filebeat.version}\n`;
1196
- text += `Service Running: ${filebeat.serviceRunning ? "yes " : "no "}\n`;
1154
+ text += `Service Running: ${filebeat.serviceRunning ? "yes OK" : "no WARNING"}\n`;
1197
1155
  text += `Config Path: ${filebeat.configPath}\n`;
1198
1156
  if (filebeat.enabledModules.length > 0) {
1199
1157
  text += `\nEnabled Modules (${filebeat.enabledModules.length}):\n`;
@@ -1252,7 +1210,7 @@ export function registerLoggingTools(server) {
1252
1210
  }
1253
1211
  let text = "SIEM Integration — Log Forwarding Audit\n\n";
1254
1212
  text += `CIS Reference: ${audit.cisBenchmark}\n`;
1255
- text += `CIS Compliant: ${audit.cisCompliant ? "YES " : "NO "}\n\n`;
1213
+ text += `CIS Compliant: ${audit.cisCompliant ? "YES OK" : "NO WARNING"}\n\n`;
1256
1214
  text += `Rsyslog Forwarding: ${audit.rsyslogForwarding ? "configured" : "not configured"}\n`;
1257
1215
  text += `Filebeat Running: ${audit.filebeatRunning ? "yes" : "no"}\n`;
1258
1216
  if (audit.rsyslogRules.length > 0) {
@@ -1263,13 +1221,13 @@ export function registerLoggingTools(server) {
1263
1221
  }
1264
1222
  text += `\nCritical Log Source Coverage:\n`;
1265
1223
  for (const source of audit.criticalSourcesCovered) {
1266
- text += ` • ${source.source} (${source.path}): ${source.forwarded ? "forwarded " : "NOT forwarded "}\n`;
1224
+ text += ` • ${source.source} (${source.path}): ${source.forwarded ? "forwarded OK" : "NOT forwarded WARNING"}\n`;
1267
1225
  }
1268
1226
  if (audit.missingSourcesCount > 0) {
1269
- text += `\n⚠ Missing Sources: ${audit.missingSourcesCount}\n`;
1227
+ text += `\nWARNING: Missing Sources: ${audit.missingSourcesCount}\n`;
1270
1228
  }
1271
1229
  if (audit.logRotationInterferes) {
1272
- text += "\n⚠ Log rotation may interfere with forwarding\n";
1230
+ text += "\nWARNING: Log rotation may interfere with forwarding\n";
1273
1231
  }
1274
1232
  if (audit.recommendations.length > 0) {
1275
1233
  text += "\nRecommendations:\n";
@@ -1317,13 +1275,13 @@ export function registerLoggingTools(server) {
1317
1275
  }
1318
1276
  let text = "SIEM Integration — Connectivity Test\n\n";
1319
1277
  text += `Target: ${connectivity.siemHost}:${connectivity.siemPort} (${connectivity.protocol})\n\n`;
1320
- text += `DNS Resolution: ${connectivity.dnsResolution ? " " : " "}${connectivity.dnsResult}\n`;
1321
- text += `TCP Connectivity: ${connectivity.tcpConnectivity ? " " : " "}${connectivity.tcpMessage}\n`;
1278
+ text += `DNS Resolution: ${connectivity.dnsResolution ? "OK " : "FAIL "}${connectivity.dnsResult}\n`;
1279
+ text += `TCP Connectivity: ${connectivity.tcpConnectivity ? "OK " : "FAIL "}${connectivity.tcpMessage}\n`;
1322
1280
  if (connectivity.protocol === "tls") {
1323
- text += `TLS Verification: ${connectivity.tlsVerification ? " " : " "}${connectivity.tlsMessage}\n`;
1281
+ text += `TLS Verification: ${connectivity.tlsVerification ? "OK " : "FAIL "}${connectivity.tlsMessage}\n`;
1324
1282
  }
1325
- text += `Firewall: ${connectivity.firewallBlocked ? " BLOCKED" : connectivity.firewallStatus}\n`;
1326
- text += `Test Message: ${connectivity.testMessageSent ? " " : " "}${connectivity.testMessageResult}\n`;
1283
+ text += `Firewall: ${connectivity.firewallBlocked ? "WARNING: BLOCKED" : connectivity.firewallStatus}\n`;
1284
+ text += `Test Message: ${connectivity.testMessageSent ? "OK " : "FAIL "}${connectivity.testMessageResult}\n`;
1327
1285
  if (connectivity.recommendations.length > 0) {
1328
1286
  text += "\nRecommendations:\n";
1329
1287
  for (const rec of connectivity.recommendations) {
@@ -370,12 +370,12 @@ export function registerMalwareTools(server) {
370
370
  const matchResult = await executeCommand({ command: "grep", args: ["-c", "-E", grepPattern, file], timeout: 5000, toolName: "malware" });
371
371
  details.push({ file, stat: statResult.stdout.trim(), patternMatches: parseInt(matchResult.stdout.trim()) || 0 });
372
372
  }
373
- return { content: [createTextContent(JSON.stringify({ scanPath, totalSuspicious: suspiciousFiles.length, details, note: suspiciousFiles.length > 0 ? "Review these files manually — pattern matches may include legitimate code" : "No webshell patterns detected" }, null, 2))] };
373
+ return { content: [createTextContent(JSON.stringify({ scanPath, totalSuspicious: suspiciousFiles.length, details, note: suspiciousFiles.length > 0 ? "Review these files manually — pattern matches may include legitimate code" : "No webshell patterns detected" }))] };
374
374
  }
375
375
  catch (error) {
376
376
  const errMsg = error instanceof Error ? error.message : String(error);
377
377
  if (errMsg.includes("exit code 1")) {
378
- return { content: [createTextContent(JSON.stringify({ scanPath: params.path, totalSuspicious: 0, note: "No webshell patterns detected" }, null, 2))] };
378
+ return { content: [createTextContent(JSON.stringify({ scanPath: params.path, totalSuspicious: 0, note: "No webshell patterns detected" }))] };
379
379
  }
380
380
  return { content: [createErrorContent(errMsg)], isError: true };
381
381
  }
@@ -1 +1 @@
1
- {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/tools/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAi6BpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAu8CzD"}
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/tools/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2zBpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAs8CzD"}