提出 #814000: dazeb markdown-downloader 3d4394b34b6c99d81af817623af55e3384df5a6a Path Traversal情報

タイトルdazeb markdown-downloader 3d4394b34b6c99d81af817623af55e3384df5a6a Path Traversal
説明# Path Traversal Vulnerability in dazeb/markdown-downloader ## Identification - **Project:** markdown-downloader - **Repository:** https://github.com/dazeb/markdown-downloader - **Affected Version/Commit:** 3d4394b34b6c99d81af817623af55e3384df5a6a ## CVE Description The server accepts user-controlled directory parameters and directly uses them in filesystem path construction with `path.join(config.downloadDirectory, input, ...)`. Multiple tools then perform filesystem operations (`writeFile`, `readdir`, `ensureDir`) on these derived paths without enforcing a root-boundary check. This can allow path traversal via `../` sequences and may result in unauthorized file write/read/list operations outside the intended download directory. ## Affected Component - **File(s):** `src/index.ts` - **Function / Method:** `download_markdown`, `list_downloaded_files`, `create_subdirectory` - **Entry Point:** MCP tool arguments `subdirectory` / `subdirectoryName` ## Reproduction Summary 1. Call `download_markdown` with attacker-controlled `subdirectory` (e.g. `../../tmp/poc`). 2. The server constructs `path.join(config.downloadDirectory, subdirectory, filename)` and writes output using `fs.writeFile(...)`. 3. Call `list_downloaded_files` with attacker-controlled `subdirectory` and observe `fs.readdir(...)` on joined path. 4. Call `create_subdirectory` with attacker-controlled `subdirectoryName` and observe `fs.ensureDir(...)` on joined path. 5. No strict `resolve + startsWith(allowedRoot)` boundary enforcement is applied before these operations. ## Technical Details ```ts // src/index.ts (download_markdown) filepath = path.join(config.downloadDirectory, subdirectory, filename); await fs.writeFile(filepath, response.data); ``` ```ts // src/index.ts (list_downloaded_files) const listDir = subdirectory && typeof subdirectory === 'string' ? path.join(config.downloadDirectory, subdirectory) : config.downloadDirectory; const files = await fs.readdir(listDir); ``` ```ts // src/index.ts (create_subdirectory) const newSubdirectoryPath = path.join(config.downloadDirectory, subdirectoryName); await fs.ensureDir(newSubdirectoryPath); ``` ## Validation Notes - User-controlled path segments are used directly in path.join(...). - Filesystem calls are reached without explicit root-boundary validation. - Behavior is consistent with path traversal risk (directory escape via crafted relative segments). ## PoC / Screenshots - Screenshot 1: download_markdown flow (path.join + fs.writeFile) <img width="990" height="282" alt="Image" src="https://github.com/user-attachments/assets/73977529-b3e8-4f65-9a11-cb11ffb1b052" /> - Screenshot 2: list_downloaded_files flow (path.join + fs.readdir) <img width="987" height="213" alt="Image" src="https://github.com/user-attachments/assets/89421fa8-f352-4812-90bd-1ed7f91ac714" /> - Screenshot 3: create_subdirectory flow (path.join + fs.ensureDir) <img width="966" height="231" alt="Image" src="https://github.com/user-attachments/assets/67f9ced1-a247-4f6b-a2d7-a5b8afb0c9b6" />
ソース⚠️ https://github.com/dazeb/markdown-downloader/issues/12
ユーザー
 Anonymous User
送信2026年04月27日 10:42 (1 月 ago)
モデレーション2026年05月24日 11:07 (27 days later)
ステータス承諾済み
VulDBエントリ365453 [dazeb markdown-downloader 迄 3d4394b34b6c99d81af817623af55e3384df5a6a src/index.ts ディレクトリトラバーサル]
ポイント20

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!