T09 · Insecure Skill Coding Practices
- Location
scripts/call_mcp.py:129- Finding
Authorization Token Can Be Sent to an Arbitrary Server
- Content
View full analysis
Vulnerability Details
File Location:
scripts/call_mcp.py:129-135,scripts/call_mcp.py:239-252, andscripts/call_mcp.py:302-308
Vulnerability Type: Unrestricted credential destination
Risk Level: HighComplete Code Snippet
python def send_request(url, payload, stoken, session_id=None): data = json.dumps(payload).encode("utf-8") headers = { "Content-Type": "application/json", "Accept": "application/json, text/event-stream", } if stoken: headers["sToken"] = stoken if session_id: headers["Mcp-Session-Id"] = session_id req = urllib.request.Request(url, data=data, headers=headers, method="POST")python def resolve_server_url(arg_url): if arg_url: url = arg_url if not url.endswith("/"): url += "/" return url url = load_server_url() if not url: print(json.dumps({"error": "mcpServerUrl is not configured"}), file=sys.stderr, flush=True) sys.exit(1) if not url.endswith("/"): url += "/" return urlpython list_parser.add_argument("--server-url", dest="server_url", default=None, help="MCP server address") call_parser.add_argument("--server-url", dest="server_url", default=None, help="MCP server address")Technical Analysis
The client loads the stored
sTokenand adds it to every MCP HTTP request. The--server-urlcommand-line option takes precedence over the configured service URL, but the supplied destination is not restricted to the declared MCP service and is not required to use HTTPS.Consequently, a caller that can influence script arguments can redirect initialization and tool requests to an attacker-controlled origin. The authorization token is then attached to the redirected request. Supporting arbitrary MCP destinations is not ...[truncated 1622 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove
--server-urlfrom production invocations and use a fixed trusted endpoint. - If configurability is essential, enforce an exact allowlist of trusted scheme, hostname, port, and path values.
- Reject all non-HTTPS destinations before loading or attaching the token.
- Normalize and validate URLs with
urllib.parse.urlsplit; do not rely on string-prefix validation. - Disable automatic cross-origin redirects or strip
sTokenandMcp-Session-Idwhenever the redirect origin differs. - Load the token only after endpoint validation succeeds.
- Add tests proving that HTTP URLs, deceptive hostnames, alternate ports, user-information components, and cross-origin redirects are rejected.
- Remove
