From eb3ed6cf39ae3ce19e0462cff6022a3d3f3517e6 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Tue, 18 Aug 2026 15:46:09 -0700 Subject: [PATCH] fix(guardrails): reject non-canonical date formats in usage windows --- litellm/proxy/guardrails/usage_endpoints.py | 5 +++++ .../proxy/guardrails/test_usage_endpoints.py | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/litellm/proxy/guardrails/usage_endpoints.py b/litellm/proxy/guardrails/usage_endpoints.py index 494a15d8948..9d0d84dc2b1 100644 --- a/litellm/proxy/guardrails/usage_endpoints.py +++ b/litellm/proxy/guardrails/usage_endpoints.py @@ -65,6 +65,11 @@ def _resolve_usage_window(start_date: str | None, end_date: str | None) -> tuple detail="start_date and end_date must be in YYYY-MM-DD format", ) start_obj, end_obj = parsed + if (start_obj.isoformat(), end_obj.isoformat()) != (start, end): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="start_date and end_date must be in YYYY-MM-DD format", + ) if end_obj < start_obj: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, diff --git a/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py b/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py index d87e607a865..ff143bd055f 100644 --- a/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py +++ b/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py @@ -393,6 +393,17 @@ async def test_overview_rejects_malformed_dates(): assert exc.value.status_code == 400 +@pytest.mark.asyncio +async def test_overview_rejects_non_canonical_date_format(): + prisma = _prisma() + handler = _config_handler() + p1, p2 = _patches(prisma, handler) + with p1, p2, pytest.raises(HTTPException) as exc: + await guardrails_usage_overview(start_date="20260420", end_date=END, user_api_key_dict=ADMIN) + assert exc.value.status_code == 400 + assert "YYYY-MM-DD" in str(exc.value.detail) + + @pytest.mark.asyncio async def test_detail_rejects_reversed_dates(): prisma = _prisma(find_unique=_db_row())