From 47d90255ba3bf470616e1262aa6493d4c6cd9616 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 15 Apr 2026 16:23:09 -0400 Subject: [PATCH] fix(security): decrypt callback_vars on use, add roundtrip tests --- .../proxy/common_utils/test_callback_utils.py | 85 ++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/tests/test_litellm/proxy/common_utils/test_callback_utils.py b/tests/test_litellm/proxy/common_utils/test_callback_utils.py index 50758b87150..f2e9b61a8c5 100644 --- a/tests/test_litellm/proxy/common_utils/test_callback_utils.py +++ b/tests/test_litellm/proxy/common_utils/test_callback_utils.py @@ -6,6 +6,7 @@ sys.path.insert( ) # Adds the parent directory to the system path from litellm.proxy.common_utils.callback_utils import ( + encrypt_logging_callback_vars, get_remaining_tokens_and_requests_from_request_data, normalize_callback_names, redact_sensitive_logging_metadata, @@ -80,7 +81,11 @@ def test_normalize_callback_names_none_returns_empty_list(): def test_normalize_callback_names_lowercases_strings(): - assert normalize_callback_names(["SQS", "S3", "CUSTOM_CALLBACK"]) == ["sqs", "s3", "custom_callback"] + assert normalize_callback_names(["SQS", "S3", "CUSTOM_CALLBACK"]) == [ + "sqs", + "s3", + "custom_callback", + ] # --------------------------------------------------------------------------- @@ -141,7 +146,9 @@ def test_redact_does_not_mutate_original(): } original_value = metadata["logging"][0]["callback_vars"]["langfuse_secret_key"] redact_sensitive_logging_metadata(metadata) - assert metadata["logging"][0]["callback_vars"]["langfuse_secret_key"] == original_value + assert ( + metadata["logging"][0]["callback_vars"]["langfuse_secret_key"] == original_value + ) def test_redact_returns_none_for_none_input(): @@ -173,3 +180,77 @@ def test_redact_mixed_env_and_real_values(): assert vars_["langfuse_public_key"] == "os.environ/LANGFUSE_PUBLIC_KEY" assert vars_["langfuse_secret_key"] == "***" + +# --------------------------------------------------------------------------- +# encrypt_logging_callback_vars tests +# --------------------------------------------------------------------------- + + +def _make_metadata(callback_vars: dict) -> dict: + return { + "logging": [ + { + "callback_name": "langfuse", + "callback_type": "success_and_failure", + "callback_vars": callback_vars, + } + ] + } + + +def test_encrypt_returns_none_for_none(): + assert encrypt_logging_callback_vars(None) is None + + +def test_encrypt_returns_unchanged_when_no_logging_key(): + metadata = {"other_key": "value"} + result = encrypt_logging_callback_vars(metadata) + assert result == {"other_key": "value"} + + +def test_encrypt_leaves_env_var_pointers_unchanged(monkeypatch): + monkeypatch.setenv("LITELLM_SALT_KEY", "test-salt-key-1234567890123456") + metadata = _make_metadata({"langfuse_secret_key": "os.environ/LANGFUSE_SECRET_KEY"}) + result = encrypt_logging_callback_vars(metadata) + assert ( + result["logging"][0]["callback_vars"]["langfuse_secret_key"] + == "os.environ/LANGFUSE_SECRET_KEY" + ) + + +def test_encrypt_real_values_are_changed(monkeypatch): + monkeypatch.setenv("LITELLM_SALT_KEY", "test-salt-key-1234567890123456") + plaintext = "sk-lf-supersecret" + metadata = _make_metadata({"langfuse_secret_key": plaintext}) + result = encrypt_logging_callback_vars(metadata) + encrypted = result["logging"][0]["callback_vars"]["langfuse_secret_key"] + assert encrypted != plaintext + assert isinstance(encrypted, str) + + +def test_encrypt_then_decrypt_roundtrip(monkeypatch): + """Encrypt a value and confirm decrypt_value_helper returns the original.""" + monkeypatch.setenv("LITELLM_SALT_KEY", "test-salt-key-1234567890123456") + from litellm.proxy.common_utils.encrypt_decrypt_utils import decrypt_value_helper + + plaintext = "pk-lf-abc123" + metadata = _make_metadata({"langfuse_public_key": plaintext}) + encrypt_logging_callback_vars(metadata) + encrypted = metadata["logging"][0]["callback_vars"]["langfuse_public_key"] + assert encrypted != plaintext + + recovered = decrypt_value_helper( + value=encrypted, key="langfuse_public_key", return_original_value=True + ) + assert recovered == plaintext + + +def test_encrypt_mutates_in_place(monkeypatch): + """encrypt_logging_callback_vars modifies the dict in-place.""" + monkeypatch.setenv("LITELLM_SALT_KEY", "test-salt-key-1234567890123456") + metadata = _make_metadata({"langfuse_secret_key": "sk-lf-real"}) + returned = encrypt_logging_callback_vars(metadata) + assert returned is metadata + assert ( + metadata["logging"][0]["callback_vars"]["langfuse_secret_key"] != "sk-lf-real" + )