{"record":{"id":"adc06a612f0e64f9","repo":"bytedance/deer-flow","slug":"mcp-server-name-passes-exec-flag-to-comm","errorCode":null,"errorMessage":"MCP server '{name}' passes '{exec_flag}' to '{command_name}', which would run arbitrary code. Point the server at a package or module instead.","messagePattern":"MCP server '(.+?)' passes '(.+?)' to '(.+?)', which would run arbitrary code\\. Point the server at a package or module instead\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"backend/app/gateway/routers/mcp.py","lineNumber":615,"sourceCode":"    allowlisted binary into an arbitrary code evaluator.\n    \"\"\"\n    allowed_commands = _allowed_stdio_commands()\n    for name, server in request.mcp_servers.items():\n        transport_type = (server.type or \"stdio\").lower()\n        if transport_type != \"stdio\":\n            continue\n\n        command_name = _stdio_command_name(server.command, server_name=name)\n        if command_name not in allowed_commands:\n            allowed = \", \".join(sorted(allowed_commands)) or \"<none>\"\n            raise HTTPException(\n                status_code=status.HTTP_400_BAD_REQUEST,\n                detail=(f\"MCP server '{name}' uses disallowed stdio command '{command_name}'. Allowed commands: {allowed}. Configure {_MCP_STDIO_COMMAND_ALLOWLIST_ENV} to extend this list.\"),\n            )\n\n        exec_flag = _arbitrary_exec_arg(server.args, command=command_name)\n        if exec_flag is not None:\n            raise HTTPException(\n                status_code=status.HTTP_400_BAD_REQUEST,\n                detail=(f\"MCP server '{name}' passes '{exec_flag}' to '{command_name}', which would run arbitrary code. Point the server at a package or module instead.\"),\n            )\n\n        for env_name in server.env:\n            if env_name.strip().upper() in _CODE_INJECTING_ENV_VARS:\n                raise HTTPException(\n                    status_code=status.HTTP_400_BAD_REQUEST,\n                    detail=(f\"MCP server '{name}' sets environment variable '{env_name}', which would run arbitrary code at process startup.\"),\n                )\n\n\ndef _mask_server_config(server: McpServerConfigResponse) -> McpServerConfigResponse:\n    \"\"\"Return a copy of server config with sensitive fields masked.\n\n    Masks env values, header values, and removes OAuth secrets so they\n    are not exposed through the GET API endpoint.\n    \"\"\"","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/mcp.py#L597-L633","documentation":"400 raised when the args passed to an allowlisted launcher contain a flag that turns it into an arbitrary code executor — e.g. node/python -e, npx -c, or uv's --with/extras forms evaluated unsafely. The screening function _arbitrary_exec_arg detects these flags so an API caller cannot use an approved binary as a general code runner.","triggerScenarios":"Submitting args like ['-c', 'import os; ...'] to python, ['-e', 'script'] to node, or any eval-style flag detected for the chosen command; adapting a CLI recipe that uses -e into the MCP args array.","commonSituations":"Trying to shim a server with an inline script instead of packaging it; porting docker-style one-liners into MCP args; misunderstanding that the allowlist approves the binary, not arbitrary invocations of it.","solutions":["Package the code as a module/package and point the launcher at it (e.g. uvx --from ./pkg server, npx -y package)","Remove -e/-c style flags from args entirely","Run genuinely custom code as a local MCP server via a non-API mechanism (operator-managed config) rather than through the API boundary"],"exampleFix":"# before\n{\"command\": \"node\", \"args\": [\"-e\", \"require('my-server').start()\"]}\n# after\n{\"command\": \"npx\", \"args\": [\"-y\", \"my-mcp-server\"]}","handlingStrategy":"validation","validationCode":"const EXEC_FLAGS = new Set(['-e', '--eval', '-c', '--command']);\nfunction assertNoExecFlags(args: string[]) { for (const a of args) if (EXEC_FLAGS.has(a)) throw new Error(`arg ${a} turns the launcher into an arbitrary code runner; use a package/module instead`); }","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Package inline scripts as a real module before exposing them as MCP servers","Never transliterate docker run one-liners into MCP args","Run custom code as an operator-managed (file-based) server, not via the API"],"tags":["mcp","stdio","security","code-injection","http-400"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}