bug: `projectRoot` bypass allows writes outside the MCP session root
Description
claude-task-master has a workspace boundary bypass in its MCP tool context handling. When a tool argument supplies projectRoot, the server normalizes and uses that path instead of enforcing containment within the MCP session root. Therefore , MCP tools that read or write task data can operate on an attacker-selected directory outside the workspace the client exposed.
Steps to Reproduce
Prepare two task-master project directories:
/tmp/ctm-projectroot-poc/safe-root/.taskmaster/tasks/tasks.json -> title=SAFE_TASK, status=pending
/tmp/ctm-projectroot-poc/evil-root/.taskmaster/tasks/tasks.json -> title=EVIL_TASK, status=pendingStart the MCP server with the client session root set to:
file:///tmp/ctm-projectroot-poc/safe-rootThen call a task-writing tool, such as set_task_status, while supplying an external projectRoot:
{
"id": "1",
"status": "done",
"projectRoot": "/tmp/ctm-projectroot-poc/evil-root"
}Expected Behavior
The tool-supplied projectRoot should be rejected because the resolved path is outside the allowed MCP session root. Task data, .env loading, and file helpers should only operate within trusted workspace roots exposed by the client.
Actual Behavior
The workspace under the MCP session root was not modified:
safe-root task: title=SAFE_TASK, status=pendingThe external directory supplied through projectRoot was modified instead:
evil-root task: title=EVIL_TASK, status=doneEnvironment
- Task Master version: 0.43.1 (
c0c98d367c55296bfe69e65680625b6db437af02) - Node.js version: v20.18.1
- Operating system: Ubuntu 22.04 LTS, Linux 6.5.13-5-pve x86_64
- IDE (if applicable): VS Code
Source: eyaltoledano/claude-task-master