| Titre | Tumf mcp-text-editor 1.0.2 Path Traversal |
|---|
| Description | Arbitrary file read/write: path validation is a single ".." substring check with no directory confinement
Package: mcp-text-editor (PyPI)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N
CWE: CWE-22 Path Traversal (CWE-23 Relative Path Traversal; incomplete control)
### Summary
The server's _validate_file_path, which the docstring describes as ensuring the path is "allowed and secure", consists solely of rejecting paths that contain the substring "..". There is no base directory / root, no realpath/commonpath confinement. Because the tools require absolute paths, an attacker simply supplies an absolute path that contains no "..", reaching anywhere on the filesystem. The read tool returns arbitrary file contents and the edit tool creates/overwrites arbitrary files. Confirmed on 1.0.2: get_text_file_contents read /etc/passwd, and edit_text_file_contents created and overwrote files outside any intended directory.
### Details
mcp_text_editor/text_editor.py, _validate_file_path (around lines 25-40):
```python
def _validate_file_path(self, file_path: ...):
# Check for path traversal
if ".." in str(file_path):
raise ValueError(...)
```
That is the entire confinement. The read sink is text_editor.py:73 open(file_path, "r") (via read_multiple_ranges), and the write sink is text_editor.py:415 open(file_path, "w") (with parent-directory auto-creation around line 229). server.py (around line 197) requires os.path.isabs(path) for edits, so absolute out-of-bounds paths are the normal input. An absolute path like /etc/passwd or /home/user/.ssh/authorized_keys contains no "..", so it passes and is read/written.
### PoC
Re-validated on mcp-text-editor 1.0.2 by driving the real TextEditor:
```
_validate_file_path('/etc/passwd') -> ACCEPTED (no confinement)
read_multiple_ranges([{file_path:'/etc/passwd', ranges:[{start:1,end:3}]}]) ->
{'/etc/passwd': {'ranges': [{'content': 'root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin...'}]}}
```
The read returned the contents of /etc/passwd. The edit path uses the same _validate_file_path and open(file_path, "w"), so edit_text_file_contents with an absolute out-of-bounds path (for example /tmp/x or a victim file with its current hash) creates or overwrites that file (confirmed: new-file create and existing-file overwrite both succeed).
### Impact
An attacker who can influence the file_path argument (LLM-produced, prompt-injection steerable) can read any file the server process can access (secrets, keys, /etc/passwd) and create or overwrite arbitrary files (for example ~/.ssh/authorized_keys, shell rc files, application config), since there is no directory confinement. The control that is presented as a security check (_validate_file_path) is ineffective. |
|---|
| La source | ⚠️ https://github.com/tumf/mcp-text-editor/issues/22 |
|---|
| Utilisateur | geochen (UID 78995) |
|---|
| Soumission | 08/06/2026 01:58 (il y a 1 mois) |
|---|
| Modérer | 08/07/2026 19:16 (1 month later) |
|---|
| Statut | Accepté |
|---|
| Entrée VulDB | 376953 [tumf mcp-text-editor jusqu’à 1.0.2 text_editor.py _validate_file_path directory traversal] |
|---|
| Points | 20 |
|---|