fix(tui): prevent path traversal in MCP storage via server name sanitization#83
fix(tui): prevent path traversal in MCP storage via server name sanitization#83
Conversation
…ization The server_path() function was vulnerable to path traversal attacks where a malicious server name like '../../../etc/passwd' could escape the mcps directory and access arbitrary files. Changes: - Add sanitize_server_name() function that replaces dangerous characters - Add validate_server_name() for pre-validation of untrusted input - Only alphanumeric, hyphen, and underscore characters are allowed - Path separators and other special chars are replaced with underscores - Add comprehensive unit tests for path traversal prevention Security Impact: Prevents directory traversal attacks that could lead to unauthorized file access or manipulation outside the MCP storage directory. Fixes: issue #5403
Greptile OverviewGreptile SummaryThis PR successfully addresses a path traversal vulnerability in MCP server storage by implementing character sanitization for server names. Key Changes
Security AnalysisThe fix effectively prevents path traversal attacks. All file operations (save, load, remove, exists) go through Issues Found
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| src/cortex-tui/src/mcp_storage.rs | Added sanitization functions to prevent path traversal attacks in MCP server storage with comprehensive test coverage |
Sequence Diagram
sequenceDiagram
participant User
participant UI as UI Form
participant Storage as McpStorage
participant Sanitizer as sanitize_server_name()
participant FS as Filesystem
User->>UI: Enter server name<br/>"../../../etc/passwd"
UI->>Storage: save_server(server)
Storage->>Sanitizer: server_path("../../../etc/passwd")
Sanitizer->>Sanitizer: Replace '.', '/', '\' with '_'
Sanitizer-->>Storage: "________etc_passwd"
Storage->>FS: Write to mcps/________etc_passwd.json
FS-->>Storage: Success
Storage-->>UI: Saved successfully
Note over User,FS: Path traversal attack prevented!
User->>UI: Load server "../../../etc/passwd"
UI->>Storage: load_server("../../../etc/passwd")
Storage->>Sanitizer: server_path("../../../etc/passwd")
Sanitizer-->>Storage: "________etc_passwd"
Storage->>FS: Read mcps/________etc_passwd.json
FS-->>Storage: JSON content
Storage-->>UI: StoredMcpServer object
| #[allow(dead_code)] | ||
| pub fn validate_server_name(name: &str) -> bool { | ||
| !name.is_empty() | ||
| && name | ||
| .chars() | ||
| .all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') | ||
| } |
There was a problem hiding this comment.
validate_server_name is unused but should be called before saving to prevent name collision issues
The current implementation allows saving servers with invalid names (e.g., "../etc"), which get sanitized to "________etc" for the filename. This creates a collision risk where "../etc" and "________etc" would map to the same file. Consider validating names in save_server():
pub fn save_server(&self, server: &StoredMcpServer) -> Result<()> {
if !validate_server_name(&server.name) {
anyhow::bail!("Invalid server name: {}", server.name);
}
// ... rest of implementation
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cortex-tui/src/mcp_storage.rs
Line: 41:47
Comment:
`validate_server_name` is unused but should be called before saving to prevent name collision issues
The current implementation allows saving servers with invalid names (e.g., `"../etc"`), which get sanitized to `"________etc"` for the filename. This creates a collision risk where `"../etc"` and `"________etc"` would map to the same file. Consider validating names in `save_server()`:
```
pub fn save_server(&self, server: &StoredMcpServer) -> Result<()> {
if !validate_server_name(&server.name) {
anyhow::bail!("Invalid server name: {}", server.name);
}
// ... rest of implementation
}
```
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (1)
If a user creates a server with name Prompt To Fix With AIThis is a comment left during a code review.
Path: src/cortex-tui/src/mcp_storage.rs
Line: 200:206
Comment:
name mismatch between stored name field and filename can cause collisions
If a user creates a server with name `"../etc"`, it's saved as `________etc.json`, but the JSON contains `"name": "../etc"`. If another server with name `"________etc"` is created later, it will overwrite the first server's file. Consider sanitizing the name field before saving:
```suggestion
pub fn save_server(&self, server: &StoredMcpServer) -> Result<()> {
self.ensure_dir()?;
let sanitized_name = sanitize_server_name(&server.name);
let mut server = server.clone();
server.name = sanitized_name.clone();
let path = self.mcps_dir.join(format!("{}.json", sanitized_name));
```
How can I resolve this? If you propose a fix, please make it concise. |
|
Closing to consolidate: This path traversal fix will be merged with PR #81 (session storage path traversal) into a consolidated security PR for path traversal prevention. |
…sion storage ## Summary This PR consolidates **2 security fixes** for path traversal vulnerabilities. ### Included PRs: - #81: Prevent path traversal in session storage via session_id sanitization - #83: Prevent path traversal in MCP storage via server name sanitization ### Key Changes: - Add sanitize_session_id() function that replaces dangerous characters - Add validate_session_id() for pre-validation of untrusted input - Add sanitize_server_name() function for MCP server names - Add validate_server_name() for pre-validation of MCP server names - Only alphanumeric, hyphen, and underscore characters are allowed ### Files Modified: - src/cortex-tui/src/session/storage.rs - src/cortex-tui/src/mcp_storage.rs Closes #81, #83
Summary
Prevent path traversal attacks in MCP storage by sanitizing server names.
Problem
The server_path() function was vulnerable to path traversal attacks where a malicious server name could escape the mcps directory.
Solution
Testing
Added unit tests for path traversal prevention.
Related Issue
Fixes issue #5403