test_redaction.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. """脱敏守卫:Secret、认证头、连接串、AccessKey 后四位(任务书 P1-B 安全 / P1-H)。"""
  2. from __future__ import annotations
  3. import json
  4. from clients.redaction import mask_access_key, redact_headers, redact_obj, redact_text
  5. SECRET = "S3CRET-VALUE-DO-NOT-LEAK"
  6. PASSWORD = "pw-123456"
  7. def test_mask_access_key_keeps_last_four():
  8. assert mask_access_key("TESTKPARTNER") == "****TNER"
  9. assert mask_access_key("ab") == "****"
  10. assert mask_access_key("") == ""
  11. def test_redact_text_removes_known_secret():
  12. text = f"signature computed with {SECRET} for tenant"
  13. out = redact_text(text, [SECRET])
  14. assert SECRET not in out
  15. assert "***REDACTED***" in out
  16. def test_redact_text_masks_connection_string_password():
  17. text = f"server=127.0.0.1;uid=root;password={PASSWORD};database=aidop_integration_sim"
  18. out = redact_text(text)
  19. assert PASSWORD not in out
  20. assert "aidop_integration_sim" in out
  21. def test_redact_text_masks_bearer_and_basic():
  22. assert "abc.def.ghi" not in redact_text("Authorization: Bearer abc.def.ghi")
  23. assert "dXNlcjpwdw==" not in redact_text("Authorization: Basic dXNlcjpwdw==")
  24. def test_redact_headers_masks_sensitive_headers():
  25. headers = {
  26. "X-Access-Key": "TESTKPARTNER",
  27. "X-Signature": "BASE64SIG==",
  28. "Authorization": f"Bearer {SECRET}",
  29. "X-Nonce": "n-1",
  30. }
  31. out = redact_headers(headers, [SECRET])
  32. assert out["X-Access-Key"] == "****TNER"
  33. assert out["X-Signature"] == "***REDACTED***"
  34. assert out["Authorization"] == "***REDACTED***"
  35. assert out["X-Nonce"] == "n-1"
  36. def test_redact_obj_recurses_and_masks_by_key_name():
  37. payload = {
  38. "request": {"headers": {"x-signature": "SIG", "x-access-key": "TESTKPARTNER"}},
  39. "notes": [f"secret was {SECRET}", {"password": PASSWORD}],
  40. "httpStatus": 202,
  41. }
  42. out = redact_obj(payload, [SECRET])
  43. dumped = json.dumps(out, ensure_ascii=False)
  44. assert SECRET not in dumped
  45. assert PASSWORD not in dumped
  46. assert out["request"]["headers"]["x-signature"] == "***REDACTED***"
  47. assert out["request"]["headers"]["x-access-key"] == "****TNER"
  48. assert out["httpStatus"] == 202