Skip to content

sec(mcp): JSON-RPC error responses leak internal error details #1182

@chaliy

Description

@chaliy

Summary

The MCP server includes raw error messages from internal operations in JSON-RPC error responses. When parsing fails, deserialization errors, or execution errors occur, the full Rust error message (which may include internal paths, struct names, or dependency details) is sent to the MCP client.

Threat category: TM-INF (Information Disclosure) — extends TM-INF-021
Severity: Low
Component: `crates/bashkit-cli/src/mcp.rs`

Root Cause

// Parse errors expose serde_json internal details
Err(e) => {
    let response = JsonRpcResponse::error(
        serde_json::Value::Null,
        -32700,
        format!("Parse error: {}", e),  // Raw serde error
    );
}

// Execution errors expose internal details
Err(e) => {
    let tool_result = ToolResult {
        content: vec![ContentItem {
            content_type: "text".to_string(),
            text: format!("Error: {}", e),  // Raw bashkit error
        }],
        is_error: Some(true),
    };
}

Steps to Reproduce

// Send malformed JSON-RPC request
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"bash","arguments":"not an object"}}

// Response may include:
// "Parse error: invalid type: string \"not an object\", expected struct BashToolArgs at line 1 column 78"
// This reveals internal struct names

Impact

  • Internal structure disclosure: Struct names, field names, internal error types revealed
  • Dependency fingerprinting: Error messages from serde, tokio, etc. reveal dependency versions
  • Attack surface mapping: Error details help attackers understand internal code structure

Acceptance Criteria

  • Sanitize error messages in JSON-RPC responses to remove internal details
  • Use generic error messages for clients: "invalid arguments", "execution failed", "internal error"
  • Log full error details at DEBUG level for operator debugging
  • Add test: malformed request produces sanitized error response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions