[Fix] Tighten api_key value check in credential validation#25917
[Fix] Tighten api_key value check in credential validation#25917yuneng-berri merged 2 commits intolitellm_yj_apr16from
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes a security bypass in Confidence Score: 5/5Safe to merge — the fix is minimal, correct, and well-tested with no regressions. The logic change is narrow and correct: short-circuit evaluation ensures no AttributeError on None, and the three-part guard (truthy and isinstance(str) and strip()) properly rejects all bypass values. The prior concern about missing tests has been resolved by the new parametrized test covering all documented bypass cases. No P0 or P1 findings remain. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/auth/auth_utils.py | Tightened check_complete_credentials to validate the api_key value (non-empty, non-whitespace string) instead of only checking key presence; logic is correct and handles all bypass cases. |
| tests/proxy_unit_tests/test_proxy_utils.py | Adds parametrized test_check_complete_credentials_api_key_values covering valid key, empty string, None, and whitespace-only cases; no real network calls, in correct test folder. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Incoming Request Body] --> B{api_base / base_url\nin request body?}
B -- No --> Z[Request Safe ✓]
B -- Yes --> C[check_complete_credentials]
C --> D{model present?}
D -- No --> E[return False]
D -- Yes --> F{complex provider?\nsagemaker/bedrock/vertex}
F -- Yes --> E
F -- No --> G{api_key value is\nnon-empty string?}
G -- No --> E[return False]
G -- Yes --> H[return True\nCredentials complete]
E --> I{allow_client_side_credentials\nor model-level config?}
I -- Yes --> Z
I -- No --> X[Raise ValueError\nRequest Rejected ✗]
H --> Z
Reviews (2): Last reviewed commit: "test: add parametrized tests for api_key..." | Re-trigger Greptile
| api_key_value = request_body.get("api_key") | ||
| if api_key_value and isinstance(api_key_value, str) and api_key_value.strip(): | ||
| return True | ||
|
|
||
| return False |
There was a problem hiding this comment.
No new tests for the fixed edge cases
The check_complete_credentials() fix closes a real bypass (empty string, null, whitespace-only api_key), but the test suite (test_auth_utils.py and test_proxy_utils.py) has no new parametrized cases that directly call check_complete_credentials with these inputs. The existing is_request_body_safe tests only exercise the api_base path without an api_key field at all.
Per the project's testing policy ("Always add tests"), it's worth adding at least:
@pytest.mark.parametrize("bad_key", ["", None, " ", "\t\n", 0, False])
def test_check_complete_credentials_rejects_missing_key_value(bad_key):
from litellm.proxy.auth.auth_utils import check_complete_credentials
body = {"model": "gpt-3.5-turbo", "api_base": "http://evil.com", "api_key": bad_key}
assert check_complete_credentials(body) is False
def test_check_complete_credentials_accepts_valid_key():
from litellm.proxy.auth.auth_utils import check_complete_credentials
body = {"model": "gpt-3.5-turbo", "api_base": "http://valid.com", "api_key": "sk-real-key"}
assert check_complete_credentials(body) is True
Summary
check_complete_credentials()previously checked only for the presence of theapi_keykey in the request body, without verifying the value. This allowed the check to pass with an empty string ornullvalue, causingis_request_body_safe()to treat the request as providing client-side credentials and skip its parameter validation.The fix verifies that the
api_keyvalue is a non-empty, non-whitespace string before considering credentials complete.Changes
Updated
check_complete_credentials()inlitellm/proxy/auth/auth_utils.pyto inspect the value ofapi_keyrather than just its presence in the request body.Testing
null, and whitespace-onlyapi_keyvalues now result in proxy-level rejection whenapi_baseis present.uv run pytest tests/test_litellm/proxy/auth/test_auth_utils.py— 45 passeduv run pytest tests/proxy_unit_tests/test_proxy_utils.py -k "request_body_safe"— 4 passedType
🐛 Bug Fix
✅ Test
Relevant issues