1-SEC contributors · Reviewed · Module: ai_containment

MCP Remote Route Monitoring: Reported URLs and Hostname Checks

Agent-action handling looks for MCP-related routing hints, extracts HTTP URLs from selected reported fields, and emits unauthorized_mcp_routing for a hostname outside localhost, 127.0.0.1, ::1, and internal-mcp.svc.cluster.local.

What 1-SEC checks

Agent-action handling looks for MCP-related routing hints, extracts HTTP URLs from selected reported fields, and emits unauthorized_mcp_routing for a hostname outside localhost, 127.0.0.1, ::1, and internal-mcp.svc.cluster.local. The fixtures cover an external route alert and a localhost route without that alert.

Read the implementation: extractUnauthorizedMCPRoute

Required telemetry and context

Relevant input events: agent_action, tool_call, function_call. Use a trusted producer at the real application boundary.

  • agent_id
  • action
  • tool
  • target
  • server_url
  • mcp_server_url
  • route_uri
  • target_url
  • endpoint
  • arguments (string)
  • parameters (string)
  • body (string)

Field names above describe relevant context, not a complete API request. Consult the current event contract for envelope and detail requirements. Preserve booleans, numbers, and strings as the receiving handler expects them. Agent-provided text cannot independently verify identity or authorization.

Deployment, prevention, and response

Report the actual selected endpoint from the MCP client before connecting where possible. Verify both controlled fixtures and the emitted alert type; a localhost case can still trigger unrelated checks. Apply authentication, Origin checks, destination policy, and process permissions in the client/server or gateway. No conformance to an MCP protocol version is established by these tests.

Record the source event, affected agent/host, actual target, policy decision, and response result. Review enforcement configuration separately from detection. A recommendation, selected action, dry-run record, and completed action are different outcomes.

Reproduce the source fixtures

From a checkout of the linked 1-SEC source revision, run the selected fixtures with the repository's Go toolchain. These commands run tests; they do not execute a real attack against your systems.

go test ./internal/modules/aicontainment -run '^(TestContainment_HandleEvent_UnauthorizedMCPRouting|TestContainment_HandleEvent_AllowedLocalMCPRouting)$' -count=1

Selected source fixtures passed in the relevant local package suites. Read their exact assertions: helper state and string-pattern tests do not establish MCP transport conformance, framework interception, or production prevention.

TestContainment_HandleEvent_UnauthorizedMCPRouting

Full fixture and assertions — run in its original package with its helpers.

func TestContainment_HandleEvent_UnauthorizedMCPRouting(t *testing.T) {
	cp := makeCapturingPipeline()
	c := startedModuleWithPipeline(t, cp)
	defer c.Stop()

	ev := core.NewSecurityEvent("test", "agent_action", core.SeverityInfo, "mcp route")
	ev.Details["agent_id"] = "agent-mcp"
	ev.Details["action"] = "register_mcp_server"
	ev.Details["tool"] = "mcp_client"
	ev.Details["target"] = "https://evil-mcp.com/tools"
	ev.SourceIP = "10.0.0.9"

	if err := c.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}

	if !cp.hasAlertType("unauthorized_mcp_routing") {
		t.Fatalf("expected unauthorized_mcp_routing alert; got %d alert(s)", cp.count())
	}
}
TestContainment_HandleEvent_AllowedLocalMCPRouting

Full fixture and assertions — run in its original package with its helpers.

func TestContainment_HandleEvent_AllowedLocalMCPRouting(t *testing.T) {
	cp := makeCapturingPipeline()
	c := startedModuleWithPipeline(t, cp)
	defer c.Stop()

	ev := core.NewSecurityEvent("test", "agent_action", core.SeverityInfo, "mcp route")
	ev.Details["agent_id"] = "agent-mcp"
	ev.Details["action"] = "register_mcp_server"
	ev.Details["tool"] = "mcp_client"
	ev.Details["target"] = "http://localhost:3000/tools"
	ev.SourceIP = "10.0.0.10"

	if err := c.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}

	if cp.hasAlertType("unauthorized_mcp_routing") {
		t.Fatalf("did not expect unauthorized_mcp_routing alert for localhost route; got %d alert(s)", cp.count())
	}
}

Tuning, evaluation, and coverage limits

This is a fixed hostname check on reported strings, not a network proxy, DNS resolution check, Origin validator, transport implementation, or certificate/identity verifier. Passing it does not establish safe localhost services. URL extraction and route-hint matching have their own string-format limits. An alert does not prevent the connection.

Evaluate this behavior with representative authorized activity and a controlled known-positive case. Investigate the exact rule, inputs, and state before suppressing an alert. Do not assume a hard-coded heuristic is a configurable setting. Measure your own deployment; the source fixtures do not establish a benchmark, detection rate, compliance certification, or incident-prevention claim.

Related implemented controls

Implementation reviewed at source revision fe508751a3f6d9bfe4b9bf8e6fa6b69e9b066771. Recheck the actual release and integration before deployment. Sources and corrections policy.