@n0zer0d4y/vulcan-file-ops 1.1.5 → 1.1.7

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 CHANGED
@@ -5,6 +5,49 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.7] - 2025-11-18
9
+
10
+ ### Security
11
+
12
+ - **CRITICAL**: Fixed command approval bypass vulnerability in `execute_shell` tool
13
+ - Previously, unapproved commands could execute if they didn't match dangerous patterns and `requiresApproval` was not set
14
+ - Now enforces strict whitelist: ALL commands must be in `--approved-commands` list to execute
15
+ - Affected commands that were incorrectly allowed: `dir`, `whoami`, `ipconfig`, `type`, `copy`, `move`, `ren`, `del`, `mkdir`, `rmdir`
16
+ - Added defense-in-depth: dangerous patterns now checked even on approved commands
17
+ - Enhanced error messages showing approved vs unapproved commands with helpful guidance
18
+
19
+ ### Added
20
+
21
+ - 19 comprehensive security tests for strict command whitelist enforcement
22
+ - Tests for unapproved non-dangerous commands (whoami, hostname)
23
+ - Tests for Windows-specific commands (dir, type, copy, move, ren, del, mkdir, rmdir, ipconfig)
24
+ - Regression tests ensuring all vulnerability examples are blocked
25
+ - Defense-in-depth tests for dangerous patterns on approved commands
26
+
27
+ ### Changed
28
+
29
+ - Updated 9 existing shell-tool tests to reflect new strict approval logic
30
+ - Updated error messages from "Command requires approval" to "Command not in approved list"
31
+ - Shell command path validation tests now include all necessary commands in approved list
32
+
33
+ ### Fixed
34
+
35
+ - `execute_shell` tool now properly blocks ALL unapproved commands regardless of `requiresApproval` parameter
36
+ - Closed security bypass where unapproved commands executed with default `requiresApproval=false`
37
+
38
+ ## [1.1.6] - 2025-11-16
39
+
40
+ ### Fixed
41
+
42
+ - README.md Configuration Examples: Corrected all `--approved-folders` examples to use separate array elements instead of comma-separated strings within quotes. This fixes setup failures for users with spaces in directory paths.
43
+ - Before: `"C:/Users/username/projects,C:/Users/username/documents"` (breaks with spaces)
44
+ - After: `"C:/Users/username/projects", "C:/Users/username/documents"` (works with spaces)
45
+ - Added clear guidance for paths containing spaces in MCP configuration
46
+
47
+ ### Changed
48
+
49
+ - Updated all README configuration examples to use the correct array element format for better user experience
50
+
8
51
  ## [1.1.5] - 2025-11-15
9
52
 
10
53
  ### Added
package/README.md CHANGED
@@ -61,7 +61,7 @@ This enhanced implementation provides:
61
61
  - **Advanced File Editing**: Pattern-based modifications with flexible matching and diff preview
62
62
  - **Flexible Reading Modes**: Full file, head/tail, or arbitrary line ranges
63
63
  - **Image Vision Support**: Attach images for AI analysis and description
64
- - **Directory Filtering**: Exclude unwanted folders (node_modules, dist, .git) from listings
64
+ - **Directory Filtering**: Exclude unwanted folders (node_modules, dist, .git) from listings as list_directory tool can bloat server output if these types folders, normally gitignored, are included
65
65
  - **Selective Tool Activation**: Enable only specific tools or tool categories
66
66
  - **High Performance**: Optimized search algorithms with smart recursion detection
67
67
  - **Security Controls**: Path validation, access restrictions, and shell command approval
@@ -209,7 +209,8 @@ Pre-configure specific directories for immediate access on server start:
209
209
  "args": [
210
210
  "@n0zer0d4y/vulcan-file-ops",
211
211
  "--approved-folders",
212
- "/Users/username/projects,/Users/username/documents"
212
+ "/Users/username/projects",
213
+ "/Users/username/documents"
213
214
  ]
214
215
  }
215
216
  }
@@ -226,7 +227,8 @@ Pre-configure specific directories for immediate access on server start:
226
227
  "args": [
227
228
  "@n0zer0d4y/vulcan-file-ops",
228
229
  "--approved-folders",
229
- "C:/Users/username/projects,C:/Users/username/documents"
230
+ "C:/Users/username/projects",
231
+ "C:/Users/username/documents"
230
232
  ]
231
233
  }
232
234
  }
@@ -244,7 +246,8 @@ For users running from a cloned repository (after `npm run build`):
244
246
  "command": "vulcan-file-ops",
245
247
  "args": [
246
248
  "--approved-folders",
247
- "/Users/username/projects,/Users/username/documents"
249
+ "/Users/username/projects",
250
+ "/Users/username/documents"
248
251
  ]
249
252
  }
250
253
  }
@@ -360,7 +363,8 @@ All configuration options can be combined:
360
363
  "args": [
361
364
  "@n0zer0d4y/vulcan-file-ops",
362
365
  "--approved-folders",
363
- "C:/Users/username/projects,C:/Users/username/documents",
366
+ "C:/Users/username/projects",
367
+ "C:/Users/username/documents",
364
368
  "--ignored-folders",
365
369
  "node_modules,dist,.git",
366
370
  "--approved-commands",
@@ -385,7 +389,8 @@ All configuration options can be combined:
385
389
  "args": [
386
390
  "@n0zer0d4y/vulcan-file-ops",
387
391
  "--approved-folders",
388
- "/Users/username/projects,/Users/username/documents",
392
+ "/Users/username/projects",
393
+ "/Users/username/documents",
389
394
  "--ignored-folders",
390
395
  "node_modules,dist,.git",
391
396
  "--approved-commands",
@@ -411,7 +416,8 @@ For users running from a cloned repository (after `npm run build`):
411
416
  "command": "vulcan-file-ops",
412
417
  "args": [
413
418
  "--approved-folders",
414
- "/Users/username/projects,/Users/username/documents",
419
+ "/Users/username/projects",
420
+ "/Users/username/documents",
415
421
  "--ignored-folders",
416
422
  "node_modules,dist,.git",
417
423
  "--approved-commands",
@@ -114,16 +114,26 @@ export async function handleShellTool(name, args) {
114
114
  // Extract root commands for approval checking
115
115
  const rootCommands = extractRootCommands(validatedArgs.command);
116
116
  const allApproved = rootCommands.every((cmd) => approvedCommands.has(cmd) || alwaysApprovedCommands.has(cmd));
117
- // Check for dangerous patterns
118
- const isDangerous = isDangerousCommand(validatedArgs.command);
119
- if (!allApproved && (validatedArgs.requiresApproval || isDangerous)) {
117
+ // SECURITY FIX: Block ALL unapproved commands immediately
118
+ // Previously, commands were only blocked if (!allApproved && (requiresApproval || isDangerous))
119
+ // This allowed unapproved non-dangerous commands to execute by default
120
+ if (!allApproved) {
120
121
  const unapprovedCommands = rootCommands.filter((cmd) => !approvedCommands.has(cmd) && !alwaysApprovedCommands.has(cmd));
121
- throw new Error(`Command requires approval. Unapproved commands: ${unapprovedCommands.join(", ")}\n` +
122
+ const approvedList = Array.from(approvedCommands).join(", ");
123
+ throw new Error(`Access denied: Command not in approved list.\n` +
124
+ `Unapproved commands: ${unapprovedCommands.join(", ")}\n` +
125
+ `Command: ${validatedArgs.command}\n\n` +
126
+ `Approved commands: ${approvedList || "(none configured)"}\n\n` +
127
+ `To execute this command, add it to --approved-commands configuration.`);
128
+ }
129
+ // SECURITY: Check dangerous patterns even for approved commands
130
+ // This provides defense-in-depth against accidentally approving dangerous commands
131
+ const isDangerous = isDangerousCommand(validatedArgs.command);
132
+ if (isDangerous && !validatedArgs.requiresApproval) {
133
+ throw new Error(`⚠️ Dangerous command pattern detected.\n` +
122
134
  `Command: ${validatedArgs.command}\n` +
123
- `${isDangerous
124
- ? "⚠️ Warning: This command matches dangerous patterns\n"
125
- : ""}` +
126
- `To approve, add these commands to --approved-commands or .env configuration.`);
135
+ `This command requires explicit approval.\n` +
136
+ `Set requiresApproval: true in the command arguments to proceed.`);
127
137
  }
128
138
  // SECURITY FIX: Validate working directory ALWAYS (not just if provided)
129
139
  // This prevents bypass via process.cwd() when workdir is omitted
@@ -150,7 +160,7 @@ export async function handleShellTool(name, args) {
150
160
  `Error: ${error instanceof Error ? error.message : String(error)}\n` +
151
161
  `\n` +
152
162
  `Allowed directories:\n` +
153
- allowedDirs.map(d => ` - ${d}`).join('\n') +
163
+ allowedDirs.map((d) => ` - ${d}`).join("\n") +
154
164
  `\n\n` +
155
165
  `To execute commands in this directory:\n` +
156
166
  ` 1. Register the directory using register_directory tool, OR\n` +
@@ -165,7 +175,7 @@ export async function handleShellTool(name, args) {
165
175
  if (allowedDirs.length === 0) {
166
176
  throw new Error(`Access denied: Command contains paths but no allowed directories are configured.\n` +
167
177
  `Extracted paths:\n` +
168
- extractedPaths.map(p => ` - ${p}`).join('\n') +
178
+ extractedPaths.map((p) => ` - ${p}`).join("\n") +
169
179
  `\n\nPlease configure allowed directories using --approved-folders or register_directory tool.`);
170
180
  }
171
181
  // Validate each extracted path
@@ -177,9 +187,9 @@ export async function handleShellTool(name, args) {
177
187
  }
178
188
  if (invalidPaths.length > 0) {
179
189
  throw new Error(`Access denied: Command contains paths outside allowed directories:\n` +
180
- invalidPaths.map(p => ` - ${p}`).join('\n') +
190
+ invalidPaths.map((p) => ` - ${p}`).join("\n") +
181
191
  `\n\nAllowed directories:\n` +
182
- allowedDirs.map(d => ` - ${d}`).join('\n') +
192
+ allowedDirs.map((d) => ` - ${d}`).join("\n") +
183
193
  `\n\nTo access these paths, register their parent directories using register_directory tool.`);
184
194
  }
185
195
  }
@@ -187,7 +197,7 @@ export async function handleShellTool(name, args) {
187
197
  catch (error) {
188
198
  // If path extraction fails, be conservative and block
189
199
  // (better to block than allow potentially unsafe commands)
190
- if (error instanceof Error && error.message.includes('Access denied')) {
200
+ if (error instanceof Error && error.message.includes("Access denied")) {
191
201
  throw error;
192
202
  }
193
203
  // For extraction errors, block the command to be safe
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n0zer0d4y/vulcan-file-ops",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "mcpName": "io.github.n0zer0d4y/vulcan-file-ops",
5
5
  "description": "MCP server for AI assistants: read, write, edit, and manage files securely on local filesystem.",
6
6
  "license": "MIT",