Skip to content

Commit 95c6e3e

Browse files
committed
fix: reject invalid dataplane tool schemas
Signed-off-by: lucarlig <luca.carlig@ibm.com>
1 parent e393c7b commit 95c6e3e

2 files changed

Lines changed: 20 additions & 4 deletions

File tree

mcpgateway/services/dataplane_publisher.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,13 +400,17 @@ def _build_user_data(
400400
backend_items_by_server: BackendItemsByServer,
401401
) -> dict[str, Any]:
402402
"""Build already-filtered dataplane data for one user."""
403+
visible_tools = [tool for tool in tool_rows if self._filter_for_user(tool, user_email, team_ids, is_admin=is_admin)]
404+
for tool in visible_tools:
405+
if not isinstance(tool.input_schema, dict):
406+
raise ValueError(f"Tool {tool.id} has a non-object input schema")
407+
403408
tool_by_id: dict[str, ToolMetadata] = {
404409
tool.id: {
405410
"name": tool.original_name,
406-
"input_schema": tool.input_schema if isinstance(tool.input_schema, dict) else {},
411+
"input_schema": tool.input_schema,
407412
}
408-
for tool in tool_rows
409-
if self._filter_for_user(tool, user_email, team_ids, is_admin=is_admin)
413+
for tool in visible_tools
410414
}
411415

412416
return {

tests/unit/mcpgateway/services/test_dataplane_publisher.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ async def test_full_payload_generation_with_mock_db():
226226
tool2.id = "t2"
227227
tool2.name = "gw1-private_tool"
228228
tool2.original_name = "private_tool"
229-
tool2.input_schema = None
229+
tool2.input_schema = {}
230230
tool2.owner_email = "user1@example.com"
231231
tool2.team_id = "team1"
232232
tool2.visibility = "private"
@@ -338,6 +338,18 @@ async def test_full_payload_generation_with_mock_db():
338338
assert user3_backend["tool_schemas"] == {"public_tool": tool1.input_schema}
339339

340340

341+
def test_build_user_data_rejects_non_object_tool_schema():
342+
"""Dataplane snapshots fail closed when an enabled tool schema is malformed."""
343+
from unittest.mock import Mock
344+
345+
from mcpgateway.services.dataplane_publisher import DataplanePublisherService
346+
347+
tool = Mock(id="bad-tool", original_name="bad", input_schema=None, visibility="public")
348+
349+
with pytest.raises(ValueError, match="Tool bad-tool has a non-object input schema"):
350+
DataplanePublisherService()._build_user_data("user@example.com", set(), False, [], [], [], [], [tool], {})
351+
352+
341353
# ============================================================================
342354
# Edge Cases
343355
# ============================================================================

0 commit comments

Comments
 (0)