T08 · Insecure Dependencies
Error
- Location
- scripts/setup_drawio_mcp.py:20
- Finding
- Persistent MCP Configuration Executes an Unpinned Remote npm Package<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/setup_drawio_mcp.py:20` - `scripts/setup_drawio_mcp.py:159-170` - `references/mcp-config.md:107` **Vulnerability Type**: Unpinned third-party dependency and mutable remote code execution **Risk Level**: High ### Vulnerable Code ```python MCP_ENTRY = {"command": "npx", "args": ["-y", "@drawio/mcp"]} ``` The unpinned entry is subsequently inserted into the selected client's persistent MCP configuration: ```python servers = existing.get(key, {}) if SERVER_KEY in servers and not force: print(f"[=] '{SERVER_KEY}' already present in {key}. Use --force to overwrite.") print(json.dumps(existing, indent=2)) return 0 servers[SERVER_KEY] = MCP_ENTRY existing[key] = servers if dry_run: print("[dry-run] Would write:") print(json.dumps(existing, indent=2)) return 0 os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, "w", encoding="utf-8") as f: json.dump(existing, f, indent=2) ``` The Cursor one-click configuration in `references/mcp-config.md:107` also contains an unpinned encoded payload: ```text https://cursor.com/en/install-mcp?name=drawio&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBkcmF3aW8vbWNwIl19 ``` The decoded configuration is: ```json {"command":"npx","args":["-y","@drawio/mcp"]} ``` ### Technical Analysis The helper configures clients to run: ```bash npx -y @drawio/mcp ``` No exact package version is specified. Consequently, npm resolves the package version at execution time, downloads it if necessary, and runs its code. The effective code executed by the MCP client can therefore change after this Skill has been reviewed. The `-y` option suppresses the normal installation confirmation, further reducing user visibility. Because the command is written into persistent client configuration, exposure is not limited to the initial setup invocation. The package can be resolved and executed whenever the client starts or activates the MCP server. ...[truncated 1555 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require an exact package version as a command-line argument, for example: ```bash python3 scripts/setup_drawio_mcp.py --target vscode --version 1.2.3 ``` 2. Validate the version against a strict semantic-version pattern and reject missing versions, tags such as `latest`, ranges, URLs, and arbitrary npm specifications. 3. Construct the entry using the validated version: ```python package = f"@drawio/mcp@{validated_version}" mcp_entry = {"command": "npx", "args": ["-y", package]} ``` 4. Do not retain an unpinned default. The helper should fail closed when no exact version is supplied. 5. Replace the Cursor one-click payload with one containing an exact reviewed version. 6. Consider verifying package integrity through a lockfile, approved package hash, or controlled internal registry. 7. Document a deliberate update process in which new versions are reviewed and the pinned value is changed explicitly. ]]>
