fix(mcp): log how many scopes were dropped instead of their names

The dropped scope names come straight from the client request, which
CodeQL flags as log injection. Logging the count still shows the cap
kicked in for a server without putting request data in the log

Generated with AI

Co-Authored-By: Claude Code
This commit is contained in:
Gaurav Pandey 2026-10-18 16:51:11 +05:30
parent 50f60e4dd8
commit 08b6fe08b0
2 changed files with 10 additions and 5 deletions

View file

@ -901,9 +901,9 @@ def _cap_requested_scopes(requested: str | None, server: MCPServer) -> str | Non
dropped: Final = [scope for scope in scopes if scope not in configured]
if dropped:
verbose_logger.debug(
"MCP server %s: dropped requested OAuth scopes %s outside the configured scopes",
"MCP server %s: dropped %d requested OAuth scopes outside the configured scopes",
server.server_id,
dropped,
len(dropped),
)
return " ".join(scope for scope in scopes if scope in configured) or None

View file

@ -5170,17 +5170,22 @@ async def test_authorize_with_enforced_identity_binding_adds_only_openid_beyond_
@pytest.mark.asyncio
async def test_authorize_logs_dropped_scope_names_and_server_but_not_client_credentials(caplog):
@pytest.mark.parametrize(
"client_scope, dropped_count", [("all ir.incidents:read", 1), ("all admin ir.incidents:read", 2)]
)
async def test_authorize_logs_dropped_scope_count_and_server_but_not_client_credentials(
caplog, client_scope, dropped_count
):
import logging
server = _resource_server(scopes=list(_READ_SCOPES), configured_scopes=_READ_SCOPES)
with caplog.at_level(logging.DEBUG, logger="LiteLLM"):
await _upstream_authorize_scope(server, "all ir.incidents:read")
await _upstream_authorize_scope(server, client_scope)
dropped_logs = [record for record in caplog.records if "outside the configured" in record.getMessage()]
assert [record.levelno for record in dropped_logs] == [logging.DEBUG], caplog.text
message = dropped_logs[0].getMessage()
assert "'all'" in message and "res-srv" in message
assert f"dropped {dropped_count} requested" in message and "res-srv" in message
assert "ir.incidents:read" not in message
assert "gateway-client" not in message and "gateway-secret" not in message