Maicon-Bartoski-Saas/mcp-server
criticalServidor MCP em teste
This MCP server dynamically creates, runs, and manages other MCP servers as child processes. It allows users to create servers from templates or custo...
1058case "create-server-from-template": {
1059 const args = request.params.arguments as unknown as CreateServerFromTemplateArgs;
1060 if (!args.language) {
1061 throw new Error("Missing required argument: language");
1062 }
1063 let serverCode = args.code;
1064 if (!serverCode) {
1065 switch (args.language) {
1066 case "typescript":
1067 serverCode = `/* TypeScriptテンプレート */`;
1068 break;
1069 case "python":
1070 serverCode = `# Pythonテンプレート`;
1071 break;
1072 default:
1073 throw new Error(`Unsupported template language: ${args.language}`);
1074 }
1075 }
1076 const result = await serverManager.createServer(serverCode, args.language, args.dependencies);// Local-only MCP, requires compromised LLM to exploit. However, the LLM is the primary user of this tool, so a compromised LLM can directly trigger this.
The create-server-from-template tool accepts arbitrary code from the user (via the 'code' argument) and passes it directly to createServer, which writes it to a file and spawns a child process to execute it. There is no validation or sandboxing of the provided code. This allows an attacker (or compromised LLM) to execute arbitrary commands on the host system.
ImpactAn attacker can execute arbitrary code with the privileges of the MCP server process, leading to full system compromise, data exfiltration, or lateral movement.
FixImplement strict validation of the code argument. Consider using a sandboxed environment (e.g., Docker containers) to execute user-provided code. Alternatively, restrict the tool to only allow predefined templates and disallow arbitrary code.
455async installDependencies(serverDir: string, dependencies: Record<string, string>, language: string): Promise<void> {
456 switch (language) {
457 case "typescript":
458 case "javascript":
459 await this.installNodeDependencies(serverDir, dependencies);
460 break;
461 case "python":
462 await this.installPythonDependencies(serverDir, dependencies);
463 break;
464 }
465}
466
467private async installNodeDependencies(serverDir: string, dependencies: Record<string, string>): Promise<void> {
468 // ... writes package.json with user-provided dependencies
469 const installProcess = spawn(npmCommand, ["install"], { shell: true, cwd: serverDir });
470}
471
472private async installPythonDependencies(serverDir: string, dependencies: Record<string, string>): Promise<void> {
473 // ... writes requirements.txt with user-provided dependencies
474 const installProcess = spawn(pipCommand, ["install", "-r", "requirements.txt"], { shell: true, cwd: serverDir });
475}// Local-only MCP, requires compromised LLM to exploit.
The create-server-from-template tool accepts a 'dependencies' argument that is an object of package names and versions. These are written to package.json or requirements.txt and then installed via npm install or pip install. An attacker can specify malicious packages that execute arbitrary code during installation (e.g., via postinstall scripts).
ImpactAn attacker can execute arbitrary code on the host system by providing a malicious package name in the dependencies, leading to full system compromise.
FixValidate or restrict the dependencies to a whitelist of known safe packages. Alternatively, disable automatic installation of dependencies or run installation in a sandboxed environment.
615async executeToolOnServer(serverId: string, toolName: string, args: Record<string, any>): Promise<any> {
616 const server = this.servers.get(serverId);
617 if (!server) {
618 throw new Error(`Server ${serverId} not found`);
619 }
620 try {
621 const result = await server.client.callTool({
622 name: toolName,
623 arguments: args,
624 });
625 return result;
626 } catch (error) {
627 console.error(`Error executing tool on server ${serverId}:`, error);
628 throw error;
629 }
630}// Local-only MCP, requires compromised LLM to exploit.
The execute-tool tool forwards any toolName and args to the child server without any validation or filtering. Since child servers are created from user-provided code (or templates), they can expose arbitrary capabilities. This effectively allows the parent MCP server to act as a proxy to any tool on any child server, including tools that may perform dangerous operations (e.g., file read/write, shell execution).
ImpactAn attacker can leverage the execute-tool tool to invoke any tool on any child server, potentially performing actions beyond the intended scope of the parent MCP server. Combined with the ability to create arbitrary child servers, this enables full arbitrary code execution.
FixImplement a whitelist of allowed tool names or enforce a schema for tool arguments. Alternatively, restrict the execute-tool tool to only work with servers created from trusted templates.
1106case "execute-tool": {
1107 const args = request.params.arguments as unknown as ExecuteToolArgs;
1108 if (!args.serverId || !args.toolName) {
1109 throw new Error("Missing required arguments: serverId and toolName");
1110 }
1111 const result = await serverManager.executeToolOnServer(args.serverId, args.toolName, args.args || {});
1112 // ...
1113}
1114case "get-server-tools": {
1115 const args = request.params.arguments as unknown as GetServerToolsArgs;
1116 if (!args.serverId) {
1117 throw new Error("Missing required argument: serverId");
1118 }
1119 const tools = await serverManager.getServerTools(args.serverId);
1120}
1121case "delete-server": {
1122 const args = request.params.arguments as unknown as DeleteServerArgs;
1123 if (!args.serverId) {
1124 throw new Error("Missing required argument: serverId");
1125 }
1126 const result = await serverManager.deleteServer(args.serverId);
1127}// Local-only MCP, requires compromised LLM to exploit.
The serverId parameter is only checked for existence, not for format or validity beyond being in the map. While this is not directly exploitable for code execution, it could allow an attacker to enumerate valid server IDs or cause denial of service by attempting operations on non-existent servers. More importantly, the execute-tool tool forwards arbitrary arguments to the child server, which could be exploited if the child server has vulnerabilities.
ImpactLimited impact: potential information disclosure (server ID enumeration) or denial of service. However, the execute-tool tool can be used to invoke arbitrary tools on child servers, which may themselves be malicious or vulnerable.
FixValidate serverId format (e.g., UUID format) and ensure it matches expected patterns. For execute-tool, consider validating the toolName against a whitelist or schema.
126async createServer(code: string, language: string, dependencies?: Record<string, string>): Promise<string> {
127 const serverId = uuidv4();
128 const serverDir = path.join(this.serversDir, serverId);
129 try {
130 await fs.mkdir(serverDir, { recursive: true });
131 await fs.chmod(serverDir, 0o777);// Local-only MCP, requires compromised LLM to exploit.
The server directory is created using a UUID, which is safe. However, the code argument is written to a file inside that directory without sanitization. If the code contains path traversal sequences (e.g., '../'), it could potentially write files outside the intended directory. However, since the file path is constructed using path.join with a fixed filename (e.g., 'index.ts'), the risk is low.
ImpactLimited: an attacker could potentially write files to arbitrary locations if the code argument contains path traversal sequences, but the fixed filename reduces exploitability.
FixValidate that the code does not contain path traversal sequences. Use path.basename for the filename to ensure it is safe.