Security
Overview
Section titled “Overview”MCP Filesystem Ultra has undergone a full security audit (v3.13.0) with 13 vulnerability fixes across 5 severity levels, plus ongoing hardening through Go 1.26.2 (12 CVEs resolved in the Go toolchain), and an AI-era threat hardening pass (v4.1.4) addressing 5 attack vectors specific to AI-driven filesystem access.
Summary
Section titled “Summary”| Metric | Value |
|---|---|
| Vulnerabilities fixed | 13 (5 Critical + 3 High + 5 Medium) |
| CVEs resolved (Go toolchain) | 12 (via Go 1.26.2) |
| AI-era attack vectors mitigated | 5 (v4.1.4) |
| Go version | 1.26.2 |
unsafe package usage | None in production code |
| Security tests | 25+ (unit + CVE pattern tests) |
| Fuzzing | go test -fuzz on security package |
AI-Era Security Hardening (v4.1.4)
Section titled “AI-Era Security Hardening (v4.1.4)”As MCP servers are driven by AI models that process external content, novel attack vectors specific to AI-assisted filesystem access exist beyond traditional path traversal. The following five mitigations were implemented in v4.1.4.
Path Security Layer (core/path_security.go)
Section titled “Path Security Layer (core/path_security.go)”A new universal validation function validatePathSecurity() runs on every path operation regardless of whether --allowed-paths is configured. It catches three attack classes:
NTFS Alternate Data Streams (ADS)
Section titled “NTFS Alternate Data Streams (ADS)”On Windows NTFS, files can have hidden streams accessed via file.txt:streamname. These streams are invisible to list_directory and Windows Explorer, making them ideal for covert data channels.
# Attacker plants hidden payloadwrite_file("C:\project\README.md:exfil_channel", secret_content)# list_directory shows nothing unusual# Payload retrieved later:read_file("C:\project\README.md:exfil_channel")Fix: hasNTFSAlternateDataStream() rejects any path with : after the drive-letter colon. Windows-only (guarded by runtime.GOOS).
Unicode Directional Overrides and Zero-Width Characters
Section titled “Unicode Directional Overrides and Zero-Width Characters”Two sub-attacks, both blocked by findDangerousUnicodeInPath():
RTLO Extension Spoofing (U+202E): The RIGHT-TO-LEFT OVERRIDE character reverses text direction visually. innocent\u202Etxt.exe renders as innocentexe.txt in many UIs but is actually an .exe.
Zero-Width Hook Evasion (U+200B): A zero-width space inserted in a filename bypasses hook glob patterns:
write_file(".en\u200Bv") # Looks like ".env" but "*.env" hook pattern doesn't match18 dangerous code points blocked including RTLO (U+202E), zero-width space (U+200B), all Unicode bidi format characters, line separators, and soft hyphen. The entire Unicode Cf (Format) category is also blocked.
Windows Reserved Device Names
Section titled “Windows Reserved Device Names”Windows treats CON, NUL, COM1-9, LPT1-9 as device references even in paths. os.ReadFile("CON") hangs waiting for console stdin (DoS). write_file("NUL", data) silently discards data while reporting success.
Fix: isWindowsReservedName() checks base filename case-insensitively with extension stripped. Applied cross-platform for portability.
WSL Bypass Removed
Section titled “WSL Bypass Removed”Previously, any path starting with \\wsl.localhost\ or \\wsl$\ unconditionally bypassed --allowed-paths access control. This allowed reading any file in any WSL distribution regardless of restrictions:
# Before (VULNERABLE): with --allowed-paths C:\MyProjectread_file("\\wsl.localhost\Ubuntu\etc\shadow") → was ALLOWED (bypass)Fix: WSL paths now undergo the same containment check as all other paths. In open-access mode (no --allowed-paths), WSL paths remain accessible.
IsPathAllowed() – Always-On Security
Section titled “IsPathAllowed() – Always-On Security”Security checks now run unconditionally — regardless of whether --allowed-paths is configured. The function:
- Runs
validatePathSecurity()first (ADS, Unicode, reserved names) - Returns
trueif open-access mode (no AllowedPaths configured) - Otherwise performs symlink-resolved containment check
All 20 call sites across engine.go, file_operations.go, edit_operations.go, streaming_operations.go, and plan_mode.go now always call IsPathAllowed() unconditionally.
Cross-Platform Hook Execution
Section titled “Cross-Platform Hook Execution”Hook commands previously used cmd /C unconditionally, silently failing on Linux/macOS and potentially bypassing blocking hooks (failOnError:true). Fixed with OS detection:
if runtime.GOOS == "windows" { cmd = exec.CommandContext(execCtx, "cmd", "/C", hook.Command)} else { cmd = exec.CommandContext(execCtx, "sh", "-c", hook.Command)}Indirect Prompt Injection (Defense-in-Depth)
Section titled “Indirect Prompt Injection (Defense-in-Depth)”This attack class (embedding instructions in files the AI reads) cannot be fully mitigated at the server layer. Recommended defenses:
- Configure
--allowed-pathsto limit readable/writable scope to the working project - Use
pre-readhooks withfailOnError:trueto block credential file reads (*.env,*.key,id_rsa) - Review AI operations before approving writes to sensitive paths
Security Hardening
Section titled “Security Hardening”Path Traversal Protection
Section titled “Path Traversal Protection”All file operations pass through isPathAllowed(), which:
- Resolves symlinks via
filepath.EvalSymlinks()before checking containment - Verifies the resolved path is within one of the configured allowed directories
- Blocks traversal attempts (
../,..\, URL-encoded variants)
// Every tool handler calls this before any file I/Oif len(e.config.AllowedPaths) > 0 { if !e.isPathAllowed(path) { return nil, &PathError{Op: "operation", Path: path, Err: fmt.Errorf("access denied")} }}Allowed paths are resolved once at engine startup via filepath.EvalSymlinks() for consistent comparison.
Symlink Protection
Section titled “Symlink Protection”isPathAllowed()resolves symlinks before containment check, preventing symlink-based directory escapecopyDirectory()skips symlinks entirely — does not follow them during recursive copy- No symlink creation operations exposed
Secure Random Generation
Section titled “Secure Random Generation”All temporary files and backup IDs use crypto/rand (not math/rand or predictable timestamps):
- Backup IDs:
timestamp-cryptoRandomformat - Temp files during edits:
crypto/randhex suffix - Pipeline temp files:
crypto/randnames
This prevents predictable file name attacks (CWE-330).
Backup ID Sanitization
Section titled “Backup ID Sanitization”Backup IDs are sanitized before use in file paths — only alphanumeric characters, -, and _ are allowed. This prevents path traversal via crafted backup IDs.
TOCTOU Prevention
Section titled “TOCTOU Prevention”Time-of-check-to-time-of-use (TOCTOU) race conditions are mitigated by:
- Performing access control checks immediately before file operations
- Using atomic file writes (write to temp, then rename)
- Channel-based semaphore (
operationSem) limiting concurrent operations
File Permissions
Section titled “File Permissions”- Temp files:
0600(owner read/write only) - Backup metadata:
0600 - No world-readable temp files
Line Ending Normalization
Section titled “Line Ending Normalization”Risk assessment normalizes line endings (\r\n → \n) before calculating change percentages. This prevents CRLF/LF mismatches from inflating risk scores and blocking legitimate edits (fixed in v4.0.2, Bug #23).
No Unsafe Code
Section titled “No Unsafe Code”No unsafe package usage in production code. All memory management relies on Go’s garbage collector.
Go Toolchain Security
Section titled “Go Toolchain Security”Go 1.26.0 resolves 8 CVEs in the standard library:
| CVE | Package | Description |
|---|---|---|
| CVE-2024-45336 | net/http | HTTP redirect credential leak |
| CVE-2024-45341 | crypto/x509 | Certificate validation bypass |
| CVE-2025-22866 | crypto/internal/fips140/nistec | P-256 scalar multiplication timing |
| CVE-2024-45340 | os/exec | Command execution on Windows |
| CVE-2024-45339 | encoding/xml | XML parsing crash |
| CVE-2024-45337 | golang.org/x/crypto/ssh | SSH server auth bypass |
| CVE-2024-45338 | golang.org/x/net/html | HTML parser DoS |
| CVE-2025-27144 | github.com/go-jose/go-jose | JWE decryption DoS |
Vulnerability Fixes (v3.13.0)
Section titled “Vulnerability Fixes (v3.13.0)”Critical (5)
Section titled “Critical (5)”- Symlink directory escape —
isPathAllowed()now resolves symlinks before containment check - Predictable temp file names — Switched from timestamp-based to
crypto/rand - Predictable backup IDs — Switched to
crypto/randsuffix - Unrestricted recursive copy of symlinks —
copyDirectory()now skips symlinks - Backup ID path traversal — Sanitization: only
[a-zA-Z0-9_-]allowed
High (3)
Section titled “High (3)”- TOCTOU in file operations — Atomic write pattern (temp + rename)
- Unbounded directory listing —
--max-list-itemslimit (default: 500) - Unbounded search results —
--max-search-resultslimit (default: 1000)
Medium (5)
Section titled “Medium (5)”- World-readable temp files — Changed to
0600permissions - Backup metadata permissions — Changed to
0600 - No operation logging — Added audit logging system (
--log-dir) - Missing input validation on line ranges — Integer boundary checks added
- Error messages leaking internal paths — Sanitized error output
Access Control
Section titled “Access Control”Allowed Paths
Section titled “Allowed Paths”When --allowed-paths is configured (or positional args are provided), all operations are restricted to those directories:
{ "args": [ "--allowed-paths", "C:\\project\\src,C:\\project\\tests", "C:\\project\\src", "C:\\project\\tests" ]}When empty (default), there are no restrictions.
Risk Assessment
Section titled “Risk Assessment”Edit operations are assessed for risk before execution:
| Level | Condition | Behavior |
|---|---|---|
| LOW | < 20% change | Proceeds silently |
| MEDIUM | 20-74% change | Auto-proceeds with backup + risk notice |
| HIGH | 75-89% change | Auto-proceeds with backup + warning |
| CRITICAL | >= 90% change | Blocked (requires force: true) |
Only CRITICAL blocks the operation. MEDIUM and HIGH auto-proceed with an automatic backup.
Edit Safety Layer
Section titled “Edit Safety Layer”The EditSafetyValidator provides additional protection:
- Context validation (surrounding lines must match)
- Stale edit prevention (file changed since last read)
Request Normalizer
Section titled “Request Normalizer”The Request Normalizer acts as a security layer by:
- Validating and coercing parameter types (prevents type confusion)
- Rejecting malformed JSON payloads
- Sanitizing pipeline step structures
Security Testing
Section titled “Security Testing”Test Files
Section titled “Test Files”tests/security/├── security_tests.go # 10+ unit tests: dependency verification, secret detection, input validation├── cves_test.go # 15+ CVE pattern tests: path traversal, command injection, race conditions└── README.mdRunning Tests
Section titled “Running Tests”# All security testsgo test ./tests/security/...
# With race detectorgo test -race ./tests/security/...
# Fuzzinggo test -fuzz=Fuzz ./tests/security
# Specific testgo test ./tests/security -run TestPathTraversalVulnerability -vCVE Pattern Tests
Section titled “CVE Pattern Tests”| Pattern | CWE | Status |
|---|---|---|
Path traversal (../, ..\, URL-encoded) | CWE-22 | Tested |
Command injection (;, |, `, $()) | CWE-78 | Tested |
| Integer overflow in line ranges | CWE-190 | Tested |
| Race conditions (concurrent access) | CWE-362 | Tested |
No unsafe imports | CWE-242 | Verified |
| No eval/exec patterns | CWE-94 | Verified |
| Dependency vulnerabilities | — | Scanned |
Batch Scripts (Windows)
Section titled “Batch Scripts (Windows)”scripts/security/├── run_all_security_tests.bat # 9-phase orchestration script├── vulnerability_scan.bat # Dependency scanner└── run_security_tests.bat # Unit test runner# Quick dependency checkscripts\security\vulnerability_scan.bat
# Full assessment (9 phases)scripts\security\run_all_security_tests.bat --coverage --reportOptional Tools
Section titled “Optional Tools”For deeper analysis (auto-detected by scripts):
go install github.com/securego/gosec/v2/cmd/gosec@latest # Static analysisgo install github.com/sonatype-nexus-oss/nancy@latest # CVE scanninggo install github.com/google/go-licenses@latest # License complianceReporting Security Issues
Section titled “Reporting Security Issues”- Use GitHub private security advisory
- Do not create public issues for security vulnerabilities
- Include: description, reproduction steps, impact assessment, suggested fix
Last updated: March 2026 Version: 4.1.0