Security
Permission Model
Section titled “Permission Model”| Access Type | Scope | Details |
|---|---|---|
| Filesystem | Read/Write | Limited to allowed directories (CLI args or MCP Roots) |
| Network | None | Stdio transport only, no outbound connections |
| System | None | No process execution, no system calls |
Path Validation
Section titled “Path Validation”Every file operation goes through path validation:
- The path is resolved to an absolute path.
- Symlinks are resolved to their real target.
- The resolved path is checked against the allow-list.
- Path traversal attempts (
../) are blocked.
If any check fails, the operation is rejected before touching the filesystem.
WSL Path Conversion (v1.1.0)
Section titled “WSL Path Conversion (v1.1.0)”On Windows, WSL-style paths like /mnt/c/Users/foo are automatically converted to C:\Users\foo before validation. This prevents false “access denied” errors when tools are called from WSL environments.
Case-Insensitive Validation (Windows)
Section titled “Case-Insensitive Validation (Windows)”On Windows, path comparison against the allow-list is case-insensitive. This fixes scenarios where c:\users\foo and C:\Users\foo refer to the same directory but would fail strict string comparison.
Blocked Attack Vectors
Section titled “Blocked Attack Vectors”The following attack vectors are tested and blocked:
| Vector | Example | Result |
|---|---|---|
| Path traversal | ../../etc/passwd | Blocked |
| WSL path injection | /mnt/c/Windows/System32 | Converted + validated |
| Win32 namespace | \\?\C:\secret | Blocked |
| Device paths | //./COM1 | Blocked |
| Forward-slash bypass | C:/Windows/System32 | Normalized + validated |
| Cross-dir exfiltration | copy_file / move_file to outside allowed dirs | Blocked (destination validated) |
Allow-list
Section titled “Allow-list”CLI arguments
Section titled “CLI arguments”Allowed directories are passed as command-line arguments at startup:
mcp-filesystem-go-light /home/user/projects /tmp/scratchMCP Roots
Section titled “MCP Roots”The server declares the roots capability. If the MCP client provides roots via roots/list, those directories are merged into the allow-list on the first tool call. This allows clients to dynamically configure access without restarting the server.
The server can start with no CLI arguments and rely entirely on roots from the client:
mcp-filesystem-go-light # roots will be provided by the clientOnly the resulting merged list of directories (and their subdirectories) is accessible. Everything else is denied.
Atomic Writes
Section titled “Atomic Writes”write_file uses an atomic write pattern:
- Content is written to a temporary file in the same directory.
os.Rename()atomically replaces the target.- On any error, the temporary file is removed.
This prevents data loss from partial writes and eliminates race conditions. write_file_safe and chunked_write use the same pattern.
Symlink Handling
Section titled “Symlink Handling”Symlinks are followed and the real target path is validated. If a symlink points outside the allowed directories, the operation is rejected.
Rate Limiting
Section titled “Rate Limiting”A sliding-window rate limiter restricts operations to 60 calls per minute. This prevents runaway loops from consuming resources.
Reporting Vulnerabilities
Section titled “Reporting Vulnerabilities”If you find a security issue, email security@scopweb.dev. Do not open a public issue.