From b6357cd9868c223be35a4a0bde4784ee1aa29715 Mon Sep 17 00:00:00 2001 From: shivam Date: Thu, 9 Apr 2026 18:39:33 -0700 Subject: [PATCH] fix(proxy): reject non-admin spend log detail when DB is unavailable Non-admins previously skipped RBAC when prisma_client was None but could still read payloads from custom loggers. Return 403 unless admin view. Add test_ui_view_request_response_forbids_non_admin_without_db. Made-with: Cursor --- .../spend_management_endpoints.py | 19 +++++++++++----- .../test_spend_management_endpoints.py | 22 +++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/litellm/proxy/spend_tracking/spend_management_endpoints.py b/litellm/proxy/spend_tracking/spend_management_endpoints.py index 16c20250c29..27c8bcc5a0c 100644 --- a/litellm/proxy/spend_tracking/spend_management_endpoints.py +++ b/litellm/proxy/spend_tracking/spend_management_endpoints.py @@ -2070,12 +2070,21 @@ async def ui_view_request_response_for_request_id( from litellm.proxy.proxy_server import prisma_client if not _is_admin_view_safe(user_api_key_dict=user_api_key_dict): - if prisma_client is not None: - await _assert_user_can_view_request_id( - prisma_client=prisma_client, - user_api_key_dict=user_api_key_dict, - request_id=request_id, + if prisma_client is None: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail={ + "error": ( + "Cannot authorize spend log access without a database " + "connection. Connect a database or use a proxy admin key." + ) + }, ) + await _assert_user_can_view_request_id( + prisma_client=prisma_client, + user_api_key_dict=user_api_key_dict, + request_id=request_id, + ) custom_loggers = ( litellm.logging_callback_manager.get_active_additional_logging_utils_from_custom_logger() diff --git a/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py b/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py index a64919438ad..24e165a5954 100644 --- a/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py +++ b/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py @@ -318,6 +318,28 @@ async def test_assert_user_can_view_request_id_rejects_both_users_none(): assert exc_info.value.status_code == 403 +def test_ui_view_request_response_forbids_non_admin_without_db(client, monkeypatch): + """ + Without prisma, non-admins cannot be authorized to read request/response + payloads (including from custom loggers); do not skip RBAC silently. + """ + monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", None) + app.dependency_overrides[ps.user_api_key_auth] = lambda: UserAPIKeyAuth( + user_role=LitellmUserRoles.INTERNAL_USER, + user_id="user_1", + ) + try: + response = client.get( + "/spend/logs/ui/req-no-db", + headers={"Authorization": "Bearer sk-test"}, + ) + assert response.status_code == 403 + body = response.json() + assert "database" in str(body).lower() + finally: + app.dependency_overrides.pop(ps.user_api_key_auth, None) + + ignored_keys = [ "request_id", "session_id",