49 lines
1.2 KiB
Python
49 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import Any
|
|
|
|
|
|
REDACTED = "[REDACTED]"
|
|
SENSITIVE_KEY_PARTS = (
|
|
"authorization",
|
|
"api_key",
|
|
"apikey",
|
|
"access_token",
|
|
"refresh_token",
|
|
"token",
|
|
"password",
|
|
"secret",
|
|
"cookie",
|
|
"set-cookie",
|
|
)
|
|
BEARER_RE = re.compile(r"(?i)\bBearer\s+[A-Za-z0-9._~+/=-]+")
|
|
|
|
|
|
def _looks_sensitive_key(key: str) -> bool:
|
|
lowered = key.strip().lower()
|
|
return any(part in lowered for part in SENSITIVE_KEY_PARTS)
|
|
|
|
|
|
def _sanitize_string(value: str) -> str:
|
|
return BEARER_RE.sub("Bearer " + REDACTED, value)
|
|
|
|
|
|
def sanitize_for_logging(value: Any) -> Any:
|
|
if isinstance(value, dict):
|
|
cleaned: dict[str, Any] = {}
|
|
for key, item in value.items():
|
|
key_text = str(key)
|
|
if _looks_sensitive_key(key_text):
|
|
cleaned[key_text] = REDACTED
|
|
else:
|
|
cleaned[key_text] = sanitize_for_logging(item)
|
|
return cleaned
|
|
if isinstance(value, list):
|
|
return [sanitize_for_logging(item) for item in value]
|
|
if isinstance(value, tuple):
|
|
return [sanitize_for_logging(item) for item in value]
|
|
if isinstance(value, str):
|
|
return _sanitize_string(value)
|
|
return value
|