fix(guardrails): redact non-string dict values with secret key names (CWE-312)

Key-name check now fires regardless of value type: when record.args is a dict
and a key matches _SECRET_KEY_NAME_RE, the value is replaced with [REDACTED]
even if it is bytes, int, or another non-string type. Simplifies the dict
comprehension logic and closes the gap flagged in Greptile review.
This commit is contained in:
Avani-prajapati 2026-05-20 15:23:56 +05:30
parent 5696b775e1
commit a05a8f3c4f
No known key found for this signature in database
2 changed files with 14 additions and 7 deletions

View file

@ -469,13 +469,9 @@ class CredentialScrubberFilter(logging.Filter):
if isinstance(record.args, dict):
record.args = {
k: (
(
_REDACTED
if _SECRET_KEY_NAME_RE.match(k)
else _scrub_secrets(str(v))
)
if isinstance(v, str)
else v
_REDACTED
if _SECRET_KEY_NAME_RE.match(k)
else (_scrub_secrets(str(v)) if isinstance(v, str) else v)
)
for k, v in record.args.items()
}

View file

@ -201,3 +201,14 @@ class TestCredentialScrubberFilter:
f.filter(record)
assert "sk-rawsecretvalue123" not in str(record.args)
assert "[REDACTED]" in str(record.args)
def test_dict_args_secret_key_non_string_value_redacted(self):
# Branch: dict key is a secret name but value is not a str (e.g. bytes).
# Key-name check must fire regardless of value type.
from litellm._logging import CredentialScrubberFilter
f = CredentialScrubberFilter()
record = self._make_record("config %s", {"api_key": b"sk-bytessecret123"})
f.filter(record)
assert "sk-bytessecret123" not in str(record.args)
assert "[REDACTED]" in str(record.args)