mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(proxy): gate include_fallback_errors behind expose_fallback_errors_to_caller setting
Without an operator gate, any authenticated caller could set include_fallback_errors=True, trigger a fallback, and read raw upstream exception messages from the x-litellm-fallback-errors header and the litellm-fallback-metadata SSE event. Strip include_fallback_errors from request data in common_processing_pre_call_logic when expose_fallback_errors_to_caller is not set, so the router never builds the error list. Also gate _should_include_fallback_errors on the same setting as a secondary check for the streaming SSE injection path.
This commit is contained in:
parent
da85887d64
commit
e7ff3e1567
3 changed files with 27 additions and 0 deletions
|
|
@ -1037,6 +1037,8 @@ class ProxyBaseLLMRequestProcessing:
|
|||
version=version,
|
||||
proxy_config=proxy_config,
|
||||
)
|
||||
if not general_settings.get("expose_fallback_errors_to_caller"):
|
||||
self.data.pop("include_fallback_errors", None)
|
||||
if route_type in {"aresponses", "_aresponses_websocket"}:
|
||||
await _authorize_response_file_search_vector_stores(
|
||||
data=self.data,
|
||||
|
|
|
|||
|
|
@ -7097,6 +7097,8 @@ def _is_positive_int_like(value: Any) -> bool:
|
|||
|
||||
|
||||
def _should_include_fallback_errors(request_data: dict[str, object]) -> bool:
|
||||
if not general_settings.get("expose_fallback_errors_to_caller"):
|
||||
return False
|
||||
return request_data.get("include_fallback_errors") is True
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from unittest.mock import MagicMock
|
|||
import pytest
|
||||
|
||||
import litellm
|
||||
from litellm.proxy.proxy_server import _should_include_fallback_errors
|
||||
from litellm.router import Router
|
||||
from litellm.router_utils.add_retry_fallback_headers import get_hidden_params_dict
|
||||
|
||||
|
|
@ -162,3 +163,25 @@ async def test_set_response_headers_adds_model_group_to_streaming_wrapper():
|
|||
"x-existing": "keep",
|
||||
"x-litellm-model-group": "fallback-model",
|
||||
}
|
||||
|
||||
|
||||
def test_should_include_fallback_errors_gated_by_operator_setting():
|
||||
request_data: dict = {"include_fallback_errors": True}
|
||||
|
||||
import litellm.proxy.proxy_server as ps
|
||||
|
||||
original = ps.general_settings.copy() if isinstance(ps.general_settings, dict) else {}
|
||||
try:
|
||||
ps.general_settings = {}
|
||||
assert _should_include_fallback_errors(request_data) is False
|
||||
|
||||
ps.general_settings = {"expose_fallback_errors_to_caller": False}
|
||||
assert _should_include_fallback_errors(request_data) is False
|
||||
|
||||
ps.general_settings = {"expose_fallback_errors_to_caller": True}
|
||||
assert _should_include_fallback_errors(request_data) is True
|
||||
|
||||
ps.general_settings = {"expose_fallback_errors_to_caller": True}
|
||||
assert _should_include_fallback_errors({}) is False
|
||||
finally:
|
||||
ps.general_settings = original
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue