MCP-005 Cleartext or unauthenticated remote endpoint
Remote MCP servers (the url / endpoint form rather than the
local command form) ship every prompt the model issues, every
tool call the model triggers, and every result the server returns
across the network connection declared in the host config. When the
URL is http:// instead of https://, all of that data travels
unencrypted: an attacker on the wire sees the whole conversation,
including any credentials the host config inlines. When the URL is
https:// but no auth credential is declared alongside, the server
may be world-callable: anyone who can dial the URL can talk to it.
What Vulkro detects
Rule fires in two shapes:
- Cleartext: URL starts with
http://and does NOT point at a loopback host (localhost,127.0.0.1,[::1]). Severity:High. Confidence:High. Evidence signal:mcp-server-cleartext-http, weight0.7, sourcePattern. Fires regardless of whether auth is declared because the auth credential itself travels in cleartext. - Unauthenticated HTTPS: URL starts with
https://and the server has no recognisable auth indicator (no env key matchingAuthorization,Bearer,Token,API_KEY,<X>_API_KEY,<X>_TOKEN,secret; no arg matchingAuthorization:,Bearer,--api-key,--token,--auth). Severity:Medium. Confidence:Medium. Evidence signal:mcp-server-unauthenticated-https, weight0.5, sourceHeuristic. Absence of evidence is not evidence of absence; the heuristic could miss an unusual auth shape.
Loopback exemption: http://localhost:<port> and
http://127.0.0.1:<port> are exempt from the cleartext finding.
Local development is a legitimate use of plain HTTP.
Non-compliant config
{
"mcpServers": {
"remote-tool": {
"type": "http",
"url": "http://mcp.example.com/v1"
},
"open-listener": {
"type": "http",
"url": "https://mcp.example.com/v1"
}
}
}
The first entry leaks every prompt over the wire. The second
declares no Authorization or API-key indicator; the server may
accept any caller.
Compliant config
{
"mcpServers": {
"remote-tool": {
"type": "http",
"url": "https://mcp.example.com/v1",
"env": {
"Authorization": "Bearer ${MCP_TOKEN}"
}
},
"internal-tool": {
"type": "http",
"url": "https://mcp.internal.corp/v1",
"env": {
"API_KEY": "${INTERNAL_MCP_KEY}"
}
}
}
}
Remediation
- Switch the endpoint to
https://. If the upstream genuinely runs HTTP only, terminate TLS in front of it (caddy, nginx, an ssh tunnel) rather than connecting in cleartext. - Add an authentication indicator: an
Authorization: Bearer ${TOKEN}env entry, anAPI_KEYenv var, or an--api-key/--authCLI arg the server understands. - If the upstream is genuinely public and unauthenticated, document the trust assumption in your README so the next reviewer doesn't have to rediscover it.
- For local development, prefer
http://localhost:<port>(which is exempt from the cleartext finding) over connecting to a remote dev box in cleartext.
See also
vulkro mcp-audit- parent CLI command.- MCP-004 - the rule that catches the literal-in-env shape of the auth credentials this rule asks you to add.
- Confidence model - what
High,Medium,Lowmean.