mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-12 03:48:56 +00:00
fix(proxy): mask IPv6 addresses that end or start with :: across eight groups
The masking pattern allowed seven colons, so valid forms like 1:2:3:4:5:6:7:: and ::1:2:3:4:5:6:7 stayed in stored error text with disable_requester_ip_address_logging on. Also lists the request metadata walker in the recursion check, since it only walks the tree the spend log sanitizer already returned.
This commit is contained in:
parent
ed556d12ca
commit
f15c94b1d7
3 changed files with 27 additions and 1 deletions
|
|
@ -1625,7 +1625,7 @@ _REQUEST_METADATA_KEYS: Final = ("metadata", "litellm_metadata")
|
|||
_OBJECT_MAPPING: Final = TypeAdapter(Mapping[object, object])
|
||||
_OBJECT_LIST: Final = TypeAdapter(list[object])
|
||||
_IPV4_ADDRESS: Final = re.compile(r"\b(?:\d{1,3}\.){3}\d{1,3}\b")
|
||||
_IPV6_ADDRESS_CANDIDATE: Final = re.compile(r"(?<![\w:])(?:[0-9A-Fa-f]{0,4}:){2,7}[0-9A-Fa-f]{0,4}(?![\w:])")
|
||||
_IPV6_ADDRESS_CANDIDATE: Final = re.compile(r"(?<![\w:])(?:[0-9A-Fa-f]{0,4}:){2,8}[0-9A-Fa-f]{0,4}(?![\w:])")
|
||||
|
||||
|
||||
def _masked_ipv6_address(candidate: re.Match[str]) -> str:
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ IGNORE_FUNCTIONS = [
|
|||
"_replace_string_leaves", # bounded by the nesting depth of a safe_json_structure output (a finite JSON tree, no cycles possible).
|
||||
"_sort_processed_sets", # bounded by the nesting depth of the log-record extra it walks (a finite JSON tree, no cycles possible).
|
||||
"scrub_json_strings", # max depth set (MAX_SCRUB_DEPTH); fails closed by returning "[Filtered]" for anything nested past the cap.
|
||||
"_without_requester_ip_address", # walks only the fresh tree _sanitize_request_body_for_spend_logs_payload returns (mapping cycles already cut), so it never goes deeper than that sanitizer did.
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6701,3 +6701,28 @@ def test_failure_error_information_masks_ip_addresses_before_long_text_is_trunca
|
|||
assert LITELLM_TRUNCATED_PAYLOAD_FIELD in stored_text
|
||||
assert any(char.isdigit() for char in kept_head_and_tail) is not disabled
|
||||
assert sanitized["error_code"] == "500"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"address", ["203.0.113.9", "2001:db8::9", "1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7::", "::1:2:3:4:5:6:7", "fe80::1"]
|
||||
)
|
||||
def test_failure_error_information_masks_every_ip_address_form_when_ip_logging_is_disabled(
|
||||
monkeypatch: pytest.MonkeyPatch, address: str
|
||||
) -> None:
|
||||
from litellm.proxy.proxy_server import general_settings
|
||||
|
||||
monkeypatch.setitem(general_settings, "disable_requester_ip_address_logging", True)
|
||||
|
||||
sanitized: Final = sanitize_error_information_for_spend_logs(
|
||||
{
|
||||
"error_code": "403",
|
||||
"error_message": f"IP address {address} not allowed.",
|
||||
"traceback": f"peer [{address}]:443",
|
||||
}
|
||||
)
|
||||
|
||||
assert sanitized == {
|
||||
"error_code": "403",
|
||||
"error_message": "IP address REDACTED_BY_LITELM not allowed.",
|
||||
"traceback": "peer [REDACTED_BY_LITELM]:443",
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue