[security] Fix unauthenticated MCP config disclosure and stdio process execution#1646
Open
13ernkastel wants to merge 16 commits intobytedance:mainfrom
Open
[security] Fix unauthenticated MCP config disclosure and stdio process execution#164613ernkastel wants to merge 16 commits intobytedance:mainfrom
13ernkastel wants to merge 16 commits intobytedance:mainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens DeerFlow’s MCP management surface by preventing the gateway/client APIs from exposing or accepting secret-bearing transport configuration, reducing the risk of unauthenticated secret disclosure and attacker-controlled stdio process execution.
Changes:
- Restricts
/api/mcp/configread responses to a public summary (enabled,description) only. - Restricts
/api/mcp/configwrites to enabled-state toggles for existing MCP servers, preserving raw on-disk transport/env placeholder fields. - Adds focused backend regression tests and updates the backend test
PYTHONPATHso MCP-related tests run reliably.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/app/mock/api/mcp/config/route.ts | Updates mock API output to match new “public summary only” MCP response shape. |
| backend/tests/test_mcp_router.py | Adds router-level tests verifying summary-only GET, safe PUT toggles, and unknown-server rejection. |
| backend/tests/test_client.py | Updates client unit tests to match new enabled-toggle-only semantics and summary responses. |
| backend/tests/test_client_e2e.py | Updates e2e tests to validate summary-only MCP reads and safe enabled-state writes. |
| backend/packages/harness/deerflow/mcp/management.py | Introduces safe management helpers: summarization + enabled-state-only atomic persistence. |
| backend/packages/harness/deerflow/mcp/init.py | Exports new MCP management helpers at package level. |
| backend/packages/harness/deerflow/client.py | Switches client MCP APIs to summary-only reads and enabled-toggle-only updates. |
| backend/Makefile | Adjusts make test PYTHONPATH to include packages/harness for test execution. |
| backend/docs/API.md | Updates API docs to reflect summary-only GET and enabled-toggle-only PUT behavior. |
| backend/app/gateway/routers/mcp.py | Refactors gateway endpoints/models to only expose public MCP summary and accept enabled toggles. |
Credit independent issue discovery and duplicate CVE reporting. Co-authored-by: Yuval Elbar <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes a security vulnerability in DeerFlow's MCP management API.
Before this change,
/api/mcp/configreturned raw MCP server configuration, including sensitive fields such asenv,headers, and OAuth credentials, and also allowed arbitrary transport configuration to be overwritten over HTTP. DeerFlow would later consume that attacker-controlled configuration during MCP tool initialization and start the suppliedstdioprocess.As a result, the MCP settings API was not just a UI configuration surface: it exposed a path to unauthenticated secret disclosure and backend process execution.
Impact
stdioMCP rewrites/var/run/docker.sockand includes Docker tooling in the backend imageCVSS Estimate
Estimated CVSS v3.1 base score:
9.8 (Critical)Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HRationale:
AV:N: reachable over the network through the exposed HTTP APIAC:L: no unusual race, brute force, or environmental precondition is required once the API is reachablePR:N: no authentication is requiredUI:N: no victim interaction is requiredS:U: the direct impact is on the DeerFlow backend runtime itselfC:H/I:H/A:H: the issue exposes secrets and enables attacker-controlled process execution, which can fully compromise confidentiality, integrity, and availability of the backend serviceThe shipped Docker deployment can make the practical impact even worse because backend code execution may be chained into host-level Docker control via the mounted Docker socket.
Benign PoC
Because this PR is public, the PoC below is intentionally non-destructive.
1. Read secret-bearing MCP config over HTTP
Pre-fix response shape:
{ "mcp_servers": { "github": { "enabled": true, "type": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "..." }, "description": "GitHub operations" } } }2. Rewrite an existing MCP server to a benign
stdiopayloadOn the next MCP tool initialization / agent run, DeerFlow would load that rewritten config and attempt to launch the configured
stdioprocess. In local validation, a benign marker file was created before MCP initialization failed, which confirms that the attacker-controlled process was started.Fix
This patch removes the exploit primitives from the HTTP management surface while keeping the MCP settings UI functional:
enabledanddescriptionextensions_config.jsontransport definitions and env placeholders on diskmake testentrypoint with the workspace layout so the MCP regression tests run correctly in CI/local validationWhy This Helps
This fix breaks the verified chain at the management boundary:
stdiocommand rewritesAfter this change, the MCP settings API is no longer a remote transport editor for local process execution.
Further Hardening
/api/mcp/configdirectly through production-facing reverse proxies without an authenticated admin boundaryValidation
Result:
1195 passed, 15 skippedAcknowledgment
Also credit @YuvalElbar6 for independently highlighting and privately reporting the same issue based on her own research. She separately submitted a duplicate CVE request before noticing this public PR, then promptly confirmed the duplicate. There is no public issue to link because her report was submitted through a private security channel.