defense-mcp-server 0.6.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.
Files changed (186) hide show
  1. package/CHANGELOG.md +471 -0
  2. package/LICENSE +21 -0
  3. package/README.md +242 -0
  4. package/build/core/auto-installer.d.ts +102 -0
  5. package/build/core/auto-installer.d.ts.map +1 -0
  6. package/build/core/auto-installer.js +833 -0
  7. package/build/core/backup-manager.d.ts +63 -0
  8. package/build/core/backup-manager.d.ts.map +1 -0
  9. package/build/core/backup-manager.js +189 -0
  10. package/build/core/changelog.d.ts +75 -0
  11. package/build/core/changelog.d.ts.map +1 -0
  12. package/build/core/changelog.js +123 -0
  13. package/build/core/command-allowlist.d.ts +129 -0
  14. package/build/core/command-allowlist.d.ts.map +1 -0
  15. package/build/core/command-allowlist.js +849 -0
  16. package/build/core/config.d.ts +79 -0
  17. package/build/core/config.d.ts.map +1 -0
  18. package/build/core/config.js +193 -0
  19. package/build/core/dependency-validator.d.ts +106 -0
  20. package/build/core/dependency-validator.d.ts.map +1 -0
  21. package/build/core/dependency-validator.js +405 -0
  22. package/build/core/distro-adapter.d.ts +177 -0
  23. package/build/core/distro-adapter.d.ts.map +1 -0
  24. package/build/core/distro-adapter.js +481 -0
  25. package/build/core/distro.d.ts +68 -0
  26. package/build/core/distro.d.ts.map +1 -0
  27. package/build/core/distro.js +457 -0
  28. package/build/core/encrypted-state.d.ts +76 -0
  29. package/build/core/encrypted-state.d.ts.map +1 -0
  30. package/build/core/encrypted-state.js +209 -0
  31. package/build/core/executor.d.ts +56 -0
  32. package/build/core/executor.d.ts.map +1 -0
  33. package/build/core/executor.js +350 -0
  34. package/build/core/installer.d.ts +92 -0
  35. package/build/core/installer.d.ts.map +1 -0
  36. package/build/core/installer.js +1072 -0
  37. package/build/core/logger.d.ts +102 -0
  38. package/build/core/logger.d.ts.map +1 -0
  39. package/build/core/logger.js +132 -0
  40. package/build/core/parsers.d.ts +151 -0
  41. package/build/core/parsers.d.ts.map +1 -0
  42. package/build/core/parsers.js +479 -0
  43. package/build/core/policy-engine.d.ts +170 -0
  44. package/build/core/policy-engine.d.ts.map +1 -0
  45. package/build/core/policy-engine.js +656 -0
  46. package/build/core/preflight.d.ts +157 -0
  47. package/build/core/preflight.d.ts.map +1 -0
  48. package/build/core/preflight.js +638 -0
  49. package/build/core/privilege-manager.d.ts +108 -0
  50. package/build/core/privilege-manager.d.ts.map +1 -0
  51. package/build/core/privilege-manager.js +363 -0
  52. package/build/core/rate-limiter.d.ts +67 -0
  53. package/build/core/rate-limiter.d.ts.map +1 -0
  54. package/build/core/rate-limiter.js +129 -0
  55. package/build/core/rollback.d.ts +73 -0
  56. package/build/core/rollback.d.ts.map +1 -0
  57. package/build/core/rollback.js +278 -0
  58. package/build/core/safeguards.d.ts +58 -0
  59. package/build/core/safeguards.d.ts.map +1 -0
  60. package/build/core/safeguards.js +448 -0
  61. package/build/core/sanitizer.d.ts +118 -0
  62. package/build/core/sanitizer.d.ts.map +1 -0
  63. package/build/core/sanitizer.js +459 -0
  64. package/build/core/secure-fs.d.ts +67 -0
  65. package/build/core/secure-fs.d.ts.map +1 -0
  66. package/build/core/secure-fs.js +143 -0
  67. package/build/core/spawn-safe.d.ts +55 -0
  68. package/build/core/spawn-safe.d.ts.map +1 -0
  69. package/build/core/spawn-safe.js +146 -0
  70. package/build/core/sudo-guard.d.ts +145 -0
  71. package/build/core/sudo-guard.d.ts.map +1 -0
  72. package/build/core/sudo-guard.js +349 -0
  73. package/build/core/sudo-session.d.ts +100 -0
  74. package/build/core/sudo-session.d.ts.map +1 -0
  75. package/build/core/sudo-session.js +319 -0
  76. package/build/core/tool-dependencies.d.ts +61 -0
  77. package/build/core/tool-dependencies.d.ts.map +1 -0
  78. package/build/core/tool-dependencies.js +571 -0
  79. package/build/core/tool-registry.d.ts +111 -0
  80. package/build/core/tool-registry.d.ts.map +1 -0
  81. package/build/core/tool-registry.js +656 -0
  82. package/build/core/tool-wrapper.d.ts +73 -0
  83. package/build/core/tool-wrapper.d.ts.map +1 -0
  84. package/build/core/tool-wrapper.js +296 -0
  85. package/build/index.d.ts +3 -0
  86. package/build/index.d.ts.map +1 -0
  87. package/build/index.js +247 -0
  88. package/build/tools/access-control.d.ts +9 -0
  89. package/build/tools/access-control.d.ts.map +1 -0
  90. package/build/tools/access-control.js +1818 -0
  91. package/build/tools/api-security.d.ts +12 -0
  92. package/build/tools/api-security.d.ts.map +1 -0
  93. package/build/tools/api-security.js +901 -0
  94. package/build/tools/app-hardening.d.ts +11 -0
  95. package/build/tools/app-hardening.d.ts.map +1 -0
  96. package/build/tools/app-hardening.js +768 -0
  97. package/build/tools/backup.d.ts +8 -0
  98. package/build/tools/backup.d.ts.map +1 -0
  99. package/build/tools/backup.js +381 -0
  100. package/build/tools/cloud-security.d.ts +17 -0
  101. package/build/tools/cloud-security.d.ts.map +1 -0
  102. package/build/tools/cloud-security.js +739 -0
  103. package/build/tools/compliance.d.ts +10 -0
  104. package/build/tools/compliance.d.ts.map +1 -0
  105. package/build/tools/compliance.js +1225 -0
  106. package/build/tools/container-security.d.ts +14 -0
  107. package/build/tools/container-security.d.ts.map +1 -0
  108. package/build/tools/container-security.js +788 -0
  109. package/build/tools/deception.d.ts +13 -0
  110. package/build/tools/deception.d.ts.map +1 -0
  111. package/build/tools/deception.js +763 -0
  112. package/build/tools/dns-security.d.ts +93 -0
  113. package/build/tools/dns-security.d.ts.map +1 -0
  114. package/build/tools/dns-security.js +745 -0
  115. package/build/tools/drift-detection.d.ts +8 -0
  116. package/build/tools/drift-detection.d.ts.map +1 -0
  117. package/build/tools/drift-detection.js +326 -0
  118. package/build/tools/ebpf-security.d.ts +15 -0
  119. package/build/tools/ebpf-security.d.ts.map +1 -0
  120. package/build/tools/ebpf-security.js +294 -0
  121. package/build/tools/encryption.d.ts +9 -0
  122. package/build/tools/encryption.d.ts.map +1 -0
  123. package/build/tools/encryption.js +1667 -0
  124. package/build/tools/firewall.d.ts +9 -0
  125. package/build/tools/firewall.d.ts.map +1 -0
  126. package/build/tools/firewall.js +1398 -0
  127. package/build/tools/hardening.d.ts +10 -0
  128. package/build/tools/hardening.d.ts.map +1 -0
  129. package/build/tools/hardening.js +2654 -0
  130. package/build/tools/ids.d.ts +9 -0
  131. package/build/tools/ids.d.ts.map +1 -0
  132. package/build/tools/ids.js +624 -0
  133. package/build/tools/incident-response.d.ts +10 -0
  134. package/build/tools/incident-response.d.ts.map +1 -0
  135. package/build/tools/incident-response.js +1180 -0
  136. package/build/tools/logging.d.ts +12 -0
  137. package/build/tools/logging.d.ts.map +1 -0
  138. package/build/tools/logging.js +454 -0
  139. package/build/tools/malware.d.ts +10 -0
  140. package/build/tools/malware.d.ts.map +1 -0
  141. package/build/tools/malware.js +532 -0
  142. package/build/tools/meta.d.ts +11 -0
  143. package/build/tools/meta.d.ts.map +1 -0
  144. package/build/tools/meta.js +2278 -0
  145. package/build/tools/network-defense.d.ts +12 -0
  146. package/build/tools/network-defense.d.ts.map +1 -0
  147. package/build/tools/network-defense.js +760 -0
  148. package/build/tools/patch-management.d.ts +3 -0
  149. package/build/tools/patch-management.d.ts.map +1 -0
  150. package/build/tools/patch-management.js +708 -0
  151. package/build/tools/process-security.d.ts +12 -0
  152. package/build/tools/process-security.d.ts.map +1 -0
  153. package/build/tools/process-security.js +784 -0
  154. package/build/tools/reporting.d.ts +11 -0
  155. package/build/tools/reporting.d.ts.map +1 -0
  156. package/build/tools/reporting.js +559 -0
  157. package/build/tools/secrets.d.ts +9 -0
  158. package/build/tools/secrets.d.ts.map +1 -0
  159. package/build/tools/secrets.js +596 -0
  160. package/build/tools/siem-integration.d.ts +18 -0
  161. package/build/tools/siem-integration.d.ts.map +1 -0
  162. package/build/tools/siem-integration.js +754 -0
  163. package/build/tools/sudo-management.d.ts +18 -0
  164. package/build/tools/sudo-management.d.ts.map +1 -0
  165. package/build/tools/sudo-management.js +737 -0
  166. package/build/tools/supply-chain-security.d.ts +8 -0
  167. package/build/tools/supply-chain-security.d.ts.map +1 -0
  168. package/build/tools/supply-chain-security.js +256 -0
  169. package/build/tools/threat-intel.d.ts +22 -0
  170. package/build/tools/threat-intel.d.ts.map +1 -0
  171. package/build/tools/threat-intel.js +749 -0
  172. package/build/tools/vulnerability-management.d.ts +11 -0
  173. package/build/tools/vulnerability-management.d.ts.map +1 -0
  174. package/build/tools/vulnerability-management.js +667 -0
  175. package/build/tools/waf.d.ts +12 -0
  176. package/build/tools/waf.d.ts.map +1 -0
  177. package/build/tools/waf.js +843 -0
  178. package/build/tools/wireless-security.d.ts +19 -0
  179. package/build/tools/wireless-security.d.ts.map +1 -0
  180. package/build/tools/wireless-security.js +826 -0
  181. package/build/tools/zero-trust-network.d.ts +8 -0
  182. package/build/tools/zero-trust-network.d.ts.map +1 -0
  183. package/build/tools/zero-trust-network.js +367 -0
  184. package/docs/SAFEGUARDS.md +518 -0
  185. package/docs/TOOLS-REFERENCE.md +665 -0
  186. package/package.json +87 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * tool-wrapper.ts — Middleware that intercepts `server.tool()` registrations
3
+ * to inject pre-flight validation before tool handlers execute.
4
+ *
5
+ * This is the critical integration piece of the pre-flight validation system.
6
+ * It creates a {@link Proxy} around {@link McpServer} that wraps every tool
7
+ * handler with pre-flight checks while remaining transparent to the 29
8
+ * existing tool registration files.
9
+ *
10
+ * ## Usage
11
+ *
12
+ * ```typescript
13
+ * import { createPreflightServer } from './core/tool-wrapper.js';
14
+ *
15
+ * const rawServer = new McpServer({ name: '...', version: '...' });
16
+ * const server = createPreflightServer(rawServer);
17
+ *
18
+ * registerFirewallTools(server); // tools register on the proxy
19
+ * await rawServer.connect(transport); // connect uses the real server
20
+ * ```
21
+ *
22
+ * @module tool-wrapper
23
+ */
24
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
25
+ /** Options for the pre-flight wrapper. */
26
+ export interface WrapperOptions {
27
+ /** Additional tool names to bypass pre-flight. */
28
+ additionalBypass?: string[];
29
+ /**
30
+ * Enable/disable pre-flight globally.
31
+ * @default `true` (unless `KALI_DEFENSE_PREFLIGHT=false`)
32
+ */
33
+ enabled?: boolean;
34
+ /**
35
+ * Prepend status banners to successful responses that have warnings
36
+ * or auto-installed dependencies.
37
+ * @default `true` (unless `KALI_DEFENSE_PREFLIGHT_BANNERS=false`)
38
+ */
39
+ prependBanners?: boolean;
40
+ }
41
+ /**
42
+ * Create a proxied {@link McpServer} that wraps every `.tool()` registration
43
+ * with pre-flight validation.
44
+ *
45
+ * The proxy intercepts only the `tool` property; all other methods and
46
+ * properties pass through to the underlying server unchanged. Tool handlers
47
+ * registered through the proxy will:
48
+ *
49
+ * 1. Check if the tool is in the bypass list (sudo management tools)
50
+ * 2. Run the {@link PreflightEngine} pipeline (dependencies + privileges)
51
+ * 3. If pre-flight **fails**, return an actionable MCP error without calling
52
+ * the original handler
53
+ * 4. If pre-flight **passes with warnings**, optionally prepend a status
54
+ * banner to the tool's response
55
+ * 5. If pre-flight **passes cleanly**, call the original handler directly
56
+ *
57
+ * @param server The original `McpServer` instance
58
+ * @param options Configuration overrides
59
+ * @returns A proxied `McpServer` — callers don't need to change their types
60
+ */
61
+ export declare function createPreflightServer(server: McpServer, options?: WrapperOptions): McpServer;
62
+ /**
63
+ * Invalidate all pre-flight caches.
64
+ *
65
+ * Call this after events that change the system state, such as:
66
+ * - `sudo_elevate` (privilege level changed)
67
+ * - `sudo_drop` (privilege level changed)
68
+ * - Successful dependency installation
69
+ *
70
+ * Typically called from `sudo-management.ts` tool handlers.
71
+ */
72
+ export declare function invalidatePreflightCaches(): void;
73
+ //# sourceMappingURL=tool-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-wrapper.d.ts","sourceRoot":"","sources":["../../src/core/tool-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwBzE,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAeD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,cAAmB,GAC3B,SAAS,CAkDX;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD"}
@@ -0,0 +1,296 @@
1
+ /**
2
+ * tool-wrapper.ts — Middleware that intercepts `server.tool()` registrations
3
+ * to inject pre-flight validation before tool handlers execute.
4
+ *
5
+ * This is the critical integration piece of the pre-flight validation system.
6
+ * It creates a {@link Proxy} around {@link McpServer} that wraps every tool
7
+ * handler with pre-flight checks while remaining transparent to the 29
8
+ * existing tool registration files.
9
+ *
10
+ * ## Usage
11
+ *
12
+ * ```typescript
13
+ * import { createPreflightServer } from './core/tool-wrapper.js';
14
+ *
15
+ * const rawServer = new McpServer({ name: '...', version: '...' });
16
+ * const server = createPreflightServer(rawServer);
17
+ *
18
+ * registerFirewallTools(server); // tools register on the proxy
19
+ * await rawServer.connect(transport); // connect uses the real server
20
+ * ```
21
+ *
22
+ * @module tool-wrapper
23
+ */
24
+ import { PreflightEngine } from "./preflight.js";
25
+ import { ToolRegistry } from "./tool-registry.js";
26
+ import { PrivilegeManager } from "./privilege-manager.js";
27
+ import { SudoGuard } from "./sudo-guard.js";
28
+ import { RateLimiter } from "./rate-limiter.js";
29
+ // ── Constants ────────────────────────────────────────────────────────────────
30
+ /**
31
+ * Tools that always skip pre-flight because they manage the sudo session
32
+ * itself. These are checked before manifest lookup for reliability.
33
+ */
34
+ const DEFAULT_BYPASS_TOOLS = new Set([
35
+ "sudo_elevate",
36
+ "sudo_elevate_gui",
37
+ "sudo_status",
38
+ "sudo_drop",
39
+ "sudo_extend",
40
+ "preflight_batch_check",
41
+ ]);
42
+ // ── Public API ───────────────────────────────────────────────────────────────
43
+ /**
44
+ * Create a proxied {@link McpServer} that wraps every `.tool()` registration
45
+ * with pre-flight validation.
46
+ *
47
+ * The proxy intercepts only the `tool` property; all other methods and
48
+ * properties pass through to the underlying server unchanged. Tool handlers
49
+ * registered through the proxy will:
50
+ *
51
+ * 1. Check if the tool is in the bypass list (sudo management tools)
52
+ * 2. Run the {@link PreflightEngine} pipeline (dependencies + privileges)
53
+ * 3. If pre-flight **fails**, return an actionable MCP error without calling
54
+ * the original handler
55
+ * 4. If pre-flight **passes with warnings**, optionally prepend a status
56
+ * banner to the tool's response
57
+ * 5. If pre-flight **passes cleanly**, call the original handler directly
58
+ *
59
+ * @param server The original `McpServer` instance
60
+ * @param options Configuration overrides
61
+ * @returns A proxied `McpServer` — callers don't need to change their types
62
+ */
63
+ export function createPreflightServer(server, options = {}) {
64
+ const { enabled = process.env.KALI_DEFENSE_PREFLIGHT !== "false", prependBanners = process.env.KALI_DEFENSE_PREFLIGHT_BANNERS !== "false", additionalBypass = [], } = options;
65
+ // Short-circuit: if disabled globally, return the raw server untouched
66
+ if (!enabled) {
67
+ console.error("[preflight] Pre-flight validation DISABLED (KALI_DEFENSE_PREFLIGHT=false)");
68
+ return server;
69
+ }
70
+ const bypassSet = new Set([
71
+ ...DEFAULT_BYPASS_TOOLS,
72
+ ...additionalBypass,
73
+ ]);
74
+ // Eagerly initialise singletons so they're ready when tools register
75
+ const preflightEngine = PreflightEngine.instance();
76
+ const registry = ToolRegistry.instance();
77
+ // CICD-024: Rate limiter — configurable via env vars
78
+ const rateLimiter = RateLimiter.instance();
79
+ const ctx = {
80
+ enabled,
81
+ prependBanners,
82
+ bypassSet,
83
+ preflightEngine,
84
+ registry,
85
+ rateLimiter,
86
+ };
87
+ console.error("[preflight] Pre-flight validation enabled — wrapping server.tool()");
88
+ // The Proxy intercepts property access on the server. Only the `tool`
89
+ // property is replaced; everything else (connect, resource, prompt, …)
90
+ // passes through via Reflect.get.
91
+ return new Proxy(server, {
92
+ get(target, prop, receiver) {
93
+ if (prop === "tool") {
94
+ return createWrappedToolMethod(target, ctx);
95
+ }
96
+ return Reflect.get(target, prop, receiver);
97
+ },
98
+ });
99
+ }
100
+ /**
101
+ * Invalidate all pre-flight caches.
102
+ *
103
+ * Call this after events that change the system state, such as:
104
+ * - `sudo_elevate` (privilege level changed)
105
+ * - `sudo_drop` (privilege level changed)
106
+ * - Successful dependency installation
107
+ *
108
+ * Typically called from `sudo-management.ts` tool handlers.
109
+ */
110
+ export function invalidatePreflightCaches() {
111
+ PreflightEngine.instance().clearCache();
112
+ PrivilegeManager.instance().clearCache();
113
+ }
114
+ // ── Internals ────────────────────────────────────────────────────────────────
115
+ /**
116
+ * Create a replacement `.tool()` method that wraps handlers with pre-flight.
117
+ *
118
+ * The MCP SDK `McpServer.tool()` has 6 overloads with 2–6 arguments.
119
+ * In **all** overloads:
120
+ * - The **first** argument is always the tool name (`string`)
121
+ * - The **last** argument is always the handler (`Function`)
122
+ *
123
+ * This invariant lets us handle every overload uniformly:
124
+ * 1. Read `args[0]` as the tool name
125
+ * 2. Read `args[args.length - 1]` as the original handler
126
+ * 3. Replace the handler with a pre-flight-wrapped version
127
+ * 4. Forward all args to the real `server.tool()`
128
+ */
129
+ function createWrappedToolMethod(server, ctx) {
130
+ // Bind to preserve `this` context on the real McpServer
131
+ const originalTool = server.tool.bind(server);
132
+ return (...args) => {
133
+ // Sanity: need at least (name, handler)
134
+ if (args.length < 2) {
135
+ return originalTool(...args);
136
+ }
137
+ const toolName = args[0];
138
+ // ── Bypass check ─────────────────────────────────────────────────
139
+ if (shouldBypassPreflight(toolName, ctx)) {
140
+ return originalTool(...args);
141
+ }
142
+ // ── Wrap the handler ─────────────────────────────────────────────
143
+ const originalHandler = args[args.length - 1];
144
+ const wrappedHandler = createWrappedHandler(toolName, originalHandler, ctx);
145
+ // Reconstruct args with the wrapped handler in the last position
146
+ const wrappedArgs = [...args];
147
+ wrappedArgs[wrappedArgs.length - 1] = wrappedHandler;
148
+ return originalTool(...wrappedArgs);
149
+ };
150
+ }
151
+ /**
152
+ * Create a wrapped handler that runs pre-flight before the original handler.
153
+ *
154
+ * **Error safety**: if the pre-flight engine itself throws an unexpected
155
+ * error, we log to stderr and fall through to the original handler.
156
+ * Pre-flight failures must **never** prevent a tool from running when
157
+ * pre-flight is broken — only when pre-flight correctly identifies a
158
+ * blocking issue (missing binary, missing sudo session, etc.).
159
+ *
160
+ * **Sudo elevation prompts**: When a tool fails due to missing privileges
161
+ * (either at pre-flight or at runtime), the wrapper returns a structured
162
+ * elevation prompt via {@link SudoGuard} instead of a generic error.
163
+ * This ensures the AI client always knows to ask the user for their
164
+ * password and call `sudo_elevate`.
165
+ */
166
+ function createWrappedHandler(toolName, originalHandler, ctx) {
167
+ return async (...callbackArgs) => {
168
+ // Extract params from callback args for safeguard checks.
169
+ // MCP SDK tool handler signature: (params, extra) — params is always first.
170
+ const toolParams = callbackArgs.length > 0 &&
171
+ callbackArgs[0] != null &&
172
+ typeof callbackArgs[0] === "object" &&
173
+ !Array.isArray(callbackArgs[0])
174
+ ? callbackArgs[0]
175
+ : undefined;
176
+ // ── CICD-024: Rate limit check ─────────────────────────────────────
177
+ const rateLimitResult = ctx.rateLimiter.check(toolName);
178
+ if (!rateLimitResult.allowed) {
179
+ console.error(`[rate-limiter] Tool '${toolName}' rejected: ${rateLimitResult.reason}`);
180
+ return {
181
+ content: [
182
+ {
183
+ type: "text",
184
+ text: `⚠ Rate limit exceeded\n\n${rateLimitResult.reason}`,
185
+ },
186
+ ],
187
+ isError: true,
188
+ };
189
+ }
190
+ // ── Run pre-flight with error safety ─────────────────────────────
191
+ try {
192
+ const result = await ctx.preflightEngine.runPreflight(toolName, toolParams);
193
+ if (!result.passed) {
194
+ // ── Check if failure is sudo-related → return elevation prompt ──
195
+ const hasSudoIssue = result.privileges.issues.some((i) => i.type === "sudo-required" ||
196
+ i.type === "sudo-unavailable" ||
197
+ i.type === "session-expired");
198
+ if (hasSudoIssue) {
199
+ // Extract the sudo reason from the manifest or the first issue
200
+ const manifest = ctx.registry.getManifest(toolName);
201
+ const reason = manifest?.sudoReason ??
202
+ result.privileges.issues[0]?.description;
203
+ console.error(`[sudo-guard] Tool '${toolName}' requires elevation — returning prompt`);
204
+ return SudoGuard.createElevationPrompt(toolName, reason, ctx.preflightEngine.formatSummary(result));
205
+ }
206
+ // Non-sudo failure — return the standard pre-flight error
207
+ return {
208
+ content: [
209
+ {
210
+ type: "text",
211
+ text: ctx.preflightEngine.formatSummary(result),
212
+ },
213
+ ],
214
+ isError: true,
215
+ };
216
+ }
217
+ // Pre-flight PASSED — call the original handler
218
+ const toolResult = (await originalHandler(...callbackArgs));
219
+ // ── Post-execution: Check for runtime permission errors ────────
220
+ // This catches `conditional` sudo tools and edge cases where
221
+ // pre-flight passed but the command still failed due to permissions.
222
+ if (toolResult &&
223
+ SudoGuard.isResponsePermissionError(toolResult)) {
224
+ const manifest = ctx.registry.getManifest(toolName);
225
+ const reason = manifest?.sudoReason ??
226
+ "The command failed due to insufficient privileges at runtime.";
227
+ const originalText = SudoGuard.extractResponseText(toolResult);
228
+ console.error(`[sudo-guard] Runtime permission error detected for '${toolName}' — returning elevation prompt`);
229
+ return SudoGuard.createElevationPrompt(toolName, reason, originalText);
230
+ }
231
+ // Optionally prepend a status banner when there are notable items
232
+ // (warnings about optional deps, auto-installed binaries, etc.)
233
+ if (ctx.prependBanners &&
234
+ hasNotableInfo(result) &&
235
+ toolResult?.content &&
236
+ Array.isArray(toolResult.content)) {
237
+ const statusMsg = ctx.preflightEngine.formatStatusMessage(result);
238
+ if (statusMsg) {
239
+ return {
240
+ ...toolResult,
241
+ content: [
242
+ { type: "text", text: statusMsg },
243
+ ...toolResult.content,
244
+ ],
245
+ };
246
+ }
247
+ }
248
+ return toolResult;
249
+ }
250
+ catch (err) {
251
+ // Pre-flight itself threw — log and fall through to original handler
252
+ console.error(`[preflight] ⚠ Pre-flight failed unexpectedly for '${toolName}': ${err instanceof Error ? err.message : String(err)}`);
253
+ const toolResult = (await originalHandler(...callbackArgs));
254
+ // Even when pre-flight is broken, still check for runtime permission errors
255
+ if (toolResult &&
256
+ SudoGuard.isResponsePermissionError(toolResult)) {
257
+ const manifest = ctx.registry.getManifest(toolName);
258
+ const reason = manifest?.sudoReason ??
259
+ "The command failed due to insufficient privileges.";
260
+ const originalText = SudoGuard.extractResponseText(toolResult);
261
+ console.error(`[sudo-guard] Runtime permission error detected for '${toolName}' (post-preflight-failure) — returning elevation prompt`);
262
+ return SudoGuard.createElevationPrompt(toolName, reason, originalText);
263
+ }
264
+ return toolResult;
265
+ }
266
+ };
267
+ }
268
+ /**
269
+ * Determine whether a tool should bypass pre-flight entirely.
270
+ *
271
+ * A tool bypasses pre-flight if:
272
+ * 1. It's in the static {@link DEFAULT_BYPASS_TOOLS} set, OR
273
+ * 2. Its manifest in the {@link ToolRegistry} has the `bypass-preflight` tag
274
+ */
275
+ function shouldBypassPreflight(toolName, ctx) {
276
+ // Fast-path: static bypass set
277
+ if (ctx.bypassSet.has(toolName))
278
+ return true;
279
+ // Check manifest tags (secondary defence — covers tools registered
280
+ // in the registry with the tag but not in the static set)
281
+ const manifest = ctx.registry.getManifest(toolName);
282
+ if (manifest?.tags?.includes("bypass-preflight"))
283
+ return true;
284
+ return false;
285
+ }
286
+ /**
287
+ * Check whether a passing {@link PreflightResult} has information worth
288
+ * prepending to the tool output (warnings or auto-installed dependencies).
289
+ *
290
+ * When the result is clean (no warnings, no installs), returns `false`
291
+ * so the tool's output is returned unmodified.
292
+ */
293
+ function hasNotableInfo(result) {
294
+ return (result.warnings.length > 0 ||
295
+ result.dependencies.installed.length > 0);
296
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/build/index.js ADDED
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { createRequire } from "node:module";
5
+ // ── Dynamic version from package.json ────────────────────────────────────────
6
+ const require = createRequire(import.meta.url);
7
+ const { version: VERSION } = require("../package.json");
8
+ // ── Core: Dependency validation & distro detection ───────────────────────────
9
+ import { validateAllDependencies, formatValidationReport, } from "./core/dependency-validator.js";
10
+ import { getConfig } from "./core/config.js";
11
+ import { getDistroAdapter } from "./core/distro-adapter.js";
12
+ import { initializeAllowlist, verifyAllBinaries } from "./core/command-allowlist.js";
13
+ import { hardenDirPermissions } from "./core/secure-fs.js";
14
+ import { homedir } from "node:os";
15
+ import { join } from "node:path";
16
+ // ── Core: Pre-flight validation system ───────────────────────────────────────
17
+ import { createPreflightServer } from './core/tool-wrapper.js';
18
+ import { initializeRegistry } from './core/tool-registry.js';
19
+ // ── Core: Lifecycle management ───────────────────────────────────────────────
20
+ import { SudoSession } from "./core/sudo-session.js";
21
+ import { logChange, createChangeEntry } from "./core/changelog.js";
22
+ // ── Original tool modules ────────────────────────────────────────────────────
23
+ import { registerFirewallTools } from "./tools/firewall.js";
24
+ import { registerHardeningTools } from "./tools/hardening.js";
25
+ import { registerIdsTools } from "./tools/ids.js";
26
+ import { registerLoggingTools } from "./tools/logging.js";
27
+ import { registerNetworkDefenseTools } from "./tools/network-defense.js";
28
+ import { registerComplianceTools } from "./tools/compliance.js";
29
+ import { registerMalwareTools } from "./tools/malware.js";
30
+ import { registerBackupTools } from "./tools/backup.js";
31
+ import { registerAccessControlTools } from "./tools/access-control.js";
32
+ import { registerEncryptionTools } from "./tools/encryption.js";
33
+ import { registerContainerSecurityTools } from "./tools/container-security.js";
34
+ import { registerMetaTools } from "./tools/meta.js";
35
+ import { registerPatchManagementTools } from "./tools/patch-management.js";
36
+ import { registerSecretsTools } from "./tools/secrets.js";
37
+ import { registerIncidentResponseTools } from "./tools/incident-response.js";
38
+ // ── Sudo privilege management ────────────────────────────────────────────────
39
+ import { registerSudoManagementTools } from "./tools/sudo-management.js";
40
+ // ── New tool modules ─────────────────────────────────────────────────────────
41
+ import { registerSupplyChainSecurityTools } from "./tools/supply-chain-security.js";
42
+ import { registerDriftDetectionTools } from "./tools/drift-detection.js";
43
+ import { registerZeroTrustNetworkTools } from "./tools/zero-trust-network.js";
44
+ import { registerEbpfSecurityTools } from "./tools/ebpf-security.js";
45
+ import { registerAppHardeningTools } from "./tools/app-hardening.js";
46
+ // ── v0.6.0 tool modules ─────────────────────────────────────────────────────
47
+ import { registerReportingTools } from "./tools/reporting.js";
48
+ import { registerDnsSecurityTools } from "./tools/dns-security.js";
49
+ import { registerVulnerabilityManagementTools } from "./tools/vulnerability-management.js";
50
+ import { registerProcessSecurityTools } from "./tools/process-security.js";
51
+ import { registerWafTools } from "./tools/waf.js";
52
+ import { registerThreatIntelTools } from "./tools/threat-intel.js";
53
+ import { registerCloudSecurityTools } from "./tools/cloud-security.js";
54
+ import { registerApiSecurityTools } from "./tools/api-security.js";
55
+ import { registerDeceptionTools } from "./tools/deception.js";
56
+ import { registerWirelessSecurityTools } from "./tools/wireless-security.js";
57
+ import { registerSiemIntegrationTools } from "./tools/siem-integration.js";
58
+ // ── Graceful shutdown handler ────────────────────────────────────────────────
59
+ function gracefulShutdown(signal) {
60
+ console.error(`\n[shutdown] Received ${signal} — cleaning up...`);
61
+ try {
62
+ // 1. Zero the sudo password buffer
63
+ const session = SudoSession.getInstance();
64
+ if (session.isElevated()) {
65
+ session.drop();
66
+ console.error("[shutdown] Sudo session dropped, password zeroed");
67
+ }
68
+ }
69
+ catch { /* ignore if not initialized */ }
70
+ try {
71
+ // 2. Log the shutdown to changelog
72
+ logChange(createChangeEntry({
73
+ tool: "server",
74
+ action: `Server shutdown via ${signal}`,
75
+ target: "server",
76
+ before: "running",
77
+ after: "stopped",
78
+ dryRun: false,
79
+ success: true,
80
+ }));
81
+ }
82
+ catch { /* ignore if changelog unavailable */ }
83
+ console.error("[shutdown] Cleanup complete, exiting");
84
+ process.exit(0);
85
+ }
86
+ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
87
+ process.on("SIGINT", () => gracefulShutdown("SIGINT"));
88
+ // SECURITY (CORE-020): uncaughtException/unhandledRejection handlers must use
89
+ // only synchronous operations. Async operations (file writes, network, cleanup)
90
+ // are NOT guaranteed to complete after an uncaught exception. Async cleanup is
91
+ // handled by SIGTERM/SIGINT handlers above.
92
+ process.on("uncaughtException", (err) => {
93
+ console.error(`[fatal] Uncaught exception: ${err.message}`);
94
+ console.error(err.stack);
95
+ process.exit(1);
96
+ });
97
+ process.on("unhandledRejection", (reason) => {
98
+ console.error(`[fatal] Unhandled rejection: ${reason}`);
99
+ process.exit(1);
100
+ });
101
+ // ── Main entry point ─────────────────────────────────────────────────────────
102
+ async function main() {
103
+ const server = new McpServer({
104
+ name: "defense-mcp-server",
105
+ version: VERSION,
106
+ });
107
+ // ── Phase 1: Dependency Validation & Auto-Install ────────────────────────
108
+ //
109
+ // Before registering tools, validate that all required system binaries
110
+ // are present. If KALI_DEFENSE_AUTO_INSTALL=true, missing tools will be
111
+ // automatically installed via the system package manager.
112
+ //
113
+ const config = getConfig();
114
+ console.error(`Defense MCP Server v${VERSION} starting...`);
115
+ console.error(`[startup] Auto-install: ${config.autoInstall ? "ENABLED" : "DISABLED"} | ` +
116
+ `Dry-run: ${config.dryRun ? "YES" : "NO"}`);
117
+ // ── Phase 0a: Initialize command allowlist ────────────────────────────────
118
+ // Must run before any command execution (dependency validation, tool registration).
119
+ // Resolves allowlisted binary names to absolute paths on this system.
120
+ initializeAllowlist();
121
+ // ── Phase 0b: Harden existing state directories ──────────────────────────
122
+ // Fix permissions on any state files/dirs created before this security fix.
123
+ // Best-effort: silently skips if directories don't exist yet.
124
+ try {
125
+ const stateDir = join(homedir(), ".kali-defense");
126
+ hardenDirPermissions(stateDir);
127
+ // Also harden the backups subdirectory if it exists
128
+ hardenDirPermissions(join(stateDir, "backups"));
129
+ }
130
+ catch {
131
+ // Non-fatal — directories may not exist yet
132
+ }
133
+ // ── Phase 0c: Run independent async startup tasks in parallel ─────────────
134
+ // verifyAllBinaries(), getDistroAdapter(), and validateAllDependencies()
135
+ // are independent of each other — run them concurrently for faster startup.
136
+ const [binaryVerifyResult, distroResult, depValidationResult] = await Promise.allSettled([
137
+ verifyAllBinaries(),
138
+ getDistroAdapter(),
139
+ validateAllDependencies(),
140
+ ]);
141
+ // Log binary integrity results
142
+ if (binaryVerifyResult.status === "rejected") {
143
+ console.error(`[startup] ⚠️ Binary integrity verification failed (non-fatal): ${binaryVerifyResult.reason instanceof Error ? binaryVerifyResult.reason.message : String(binaryVerifyResult.reason)}`);
144
+ }
145
+ // Log distro detection results
146
+ if (distroResult.status === "fulfilled") {
147
+ console.error(`[startup] 🐧 ${distroResult.value.summary}`);
148
+ }
149
+ else {
150
+ console.error(`[startup] ⚠️ Distro detection failed: ${distroResult.reason instanceof Error ? distroResult.reason.message : String(distroResult.reason)}`);
151
+ console.error("[startup] Continuing with defaults...");
152
+ }
153
+ // Log dependency validation results
154
+ if (depValidationResult.status === "fulfilled") {
155
+ const report = depValidationResult.value;
156
+ console.error(formatValidationReport(report));
157
+ if (report.criticalMissing.length > 0 && !config.autoInstall) {
158
+ console.error("[startup] ⚠️ Some critical tools are missing. The server will start, " +
159
+ "but affected tools may fail at runtime.");
160
+ console.error("[startup] 💡 To auto-install: set KALI_DEFENSE_AUTO_INSTALL=true");
161
+ }
162
+ if (report.installed.length > 0) {
163
+ console.error(`[startup] ✅ Auto-installed ${report.installed.length} missing tools: ` +
164
+ report.installed.join(", "));
165
+ }
166
+ }
167
+ else {
168
+ console.error(`[startup] ⚠️ Dependency validation failed: ${depValidationResult.reason instanceof Error ? depValidationResult.reason.message : String(depValidationResult.reason)}`);
169
+ console.error("[startup] Continuing with server startup...");
170
+ }
171
+ // ── Phase 0.5: Initialize pre-flight validation system ───────────────────
172
+ console.error('[startup] Initializing pre-flight validation system...');
173
+ try {
174
+ const registry = initializeRegistry();
175
+ console.error(`[startup] Pre-flight registry initialized with ${registry.getAll().length} tool manifests`);
176
+ }
177
+ catch (err) {
178
+ console.error(`[startup] Pre-flight registry initialization failed (non-fatal): ${err}`);
179
+ }
180
+ // Wrap server with pre-flight middleware
181
+ const wrappedServer = createPreflightServer(server);
182
+ // ── Phase 2: Register all defensive tool modules (with error isolation) ──
183
+ let registered = 0;
184
+ let failed = 0;
185
+ const failedModules = [];
186
+ function safeRegister(name, fn) {
187
+ try {
188
+ fn(wrappedServer);
189
+ registered++;
190
+ }
191
+ catch (err) {
192
+ failed++;
193
+ failedModules.push(name);
194
+ console.error(`[startup] ⚠ Failed to register ${name} tools: ${err instanceof Error ? err.message : err}`);
195
+ }
196
+ }
197
+ // Sudo privilege management (must be registered first — prerequisite for other tools)
198
+ safeRegister("sudo-management", registerSudoManagementTools);
199
+ // Original tool modules
200
+ safeRegister("firewall", registerFirewallTools);
201
+ safeRegister("hardening", registerHardeningTools);
202
+ safeRegister("ids", registerIdsTools);
203
+ safeRegister("logging", registerLoggingTools);
204
+ safeRegister("network-defense", registerNetworkDefenseTools);
205
+ safeRegister("compliance", registerComplianceTools);
206
+ safeRegister("malware", registerMalwareTools);
207
+ safeRegister("backup", registerBackupTools);
208
+ safeRegister("access-control", registerAccessControlTools);
209
+ safeRegister("encryption", registerEncryptionTools);
210
+ safeRegister("container-security", registerContainerSecurityTools);
211
+ safeRegister("meta", registerMetaTools);
212
+ safeRegister("patch-management", registerPatchManagementTools);
213
+ safeRegister("secrets", registerSecretsTools);
214
+ safeRegister("incident-response", registerIncidentResponseTools);
215
+ // New tool modules
216
+ safeRegister("supply-chain-security", registerSupplyChainSecurityTools);
217
+ safeRegister("drift-detection", registerDriftDetectionTools);
218
+ safeRegister("zero-trust-network", registerZeroTrustNetworkTools);
219
+ safeRegister("ebpf-security", registerEbpfSecurityTools);
220
+ safeRegister("app-hardening", registerAppHardeningTools);
221
+ // v0.6.0 tool modules
222
+ safeRegister("api-security", registerApiSecurityTools);
223
+ safeRegister("cloud-security", registerCloudSecurityTools);
224
+ safeRegister("deception", registerDeceptionTools);
225
+ safeRegister("dns-security", registerDnsSecurityTools);
226
+ safeRegister("process-security", registerProcessSecurityTools);
227
+ safeRegister("reporting", registerReportingTools);
228
+ safeRegister("siem-integration", registerSiemIntegrationTools);
229
+ safeRegister("threat-intel", registerThreatIntelTools);
230
+ safeRegister("vulnerability-management", registerVulnerabilityManagementTools);
231
+ safeRegister("waf", registerWafTools);
232
+ safeRegister("wireless-security", registerWirelessSecurityTools);
233
+ // Fail hard if no modules loaded at all
234
+ if (registered === 0) {
235
+ throw new Error("No tool modules loaded — server cannot start");
236
+ }
237
+ // ── Phase 3: Connect transport ───────────────────────────────────────────
238
+ const transport = new StdioServerTransport();
239
+ await server.connect(transport);
240
+ console.error(`Defense MCP Server v${VERSION} running on stdio`);
241
+ console.error(`Registered ${registered} of ${registered + failed} tool modules with ~94 defensive security tools${failed > 0 ? ` (${failed} failed: ${failedModules.join(", ")})` : ""}`);
242
+ console.error("[startup] 💡 Use sudo_elevate to provide your password once for all privileged operations");
243
+ }
244
+ main().catch((error) => {
245
+ console.error("Fatal error:", error);
246
+ process.exit(1);
247
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Access control and authentication auditing tools for Kali Defense MCP Server.
3
+ *
4
+ * Registers 6 tools: access_ssh, access_pam, access_sudo_audit,
5
+ * access_user_audit, access_password_policy, access_restrict_shell.
6
+ */
7
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
+ export declare function registerAccessControlTools(server: McpServer): void;
9
+ //# sourceMappingURL=access-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-control.d.ts","sourceRoot":"","sources":["../../src/tools/access-control.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2LpE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA44DlE"}