From 5280dec0ee43b9bc966accc6a4d9c85870a9aec5 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sun, 13 Sep 2026 20:13:37 -0700 Subject: [PATCH] fix(redact): repr pass leaves already-masked values alone The Python-repr pass ran after the MCP probe header scrub and collapsed 'Authorization': 'Digest ***' to '***', erasing the scheme word that scrub deliberately keeps (tests/hermes_cli/test_mcp_probe_redaction.py went red on rebase). Skip values that already carry a mask marker. --- agent/redact.py | 5 +++++ tests/agent/test_redact.py | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/agent/redact.py b/agent/redact.py index 54b02a1e92..0479640e0b 100644 --- a/agent/redact.py +++ b/agent/redact.py @@ -618,6 +618,11 @@ def _redact_python_repr_fields(text: str) -> str: # programmatic env lookups just like the ENV/JSON/YAML passes do. if _ENV_LOOKUP_VALUE_RE.match(value): return match.group(0) + # An upstream pass (MCP probe header scrub, _mask_token) already masked this + # value; re-masking would erase the scheme word it deliberately kept + # (``'Authorization': 'Digest ***'`` → ``'***'``). + if "***" in value or value.startswith("«redacted:"): + return match.group(0) # Do not retain head/tail characters here: escaped repr atoms can cross # a slicing boundary and leave an unescaped quote behind. A full mask is # parseable for both str and bytes values and leaks no opaque bytes. diff --git a/tests/agent/test_redact.py b/tests/agent/test_redact.py index b703ddd6a2..3df2b82879 100644 --- a/tests/agent/test_redact.py +++ b/tests/agent/test_redact.py @@ -378,6 +378,12 @@ class TestPythonReprFields: text = "{'model': 'gpt-5', 'token_count': '123'}" assert redact_sensitive_text(text, force=True) == text + def test_already_masked_repr_value_keeps_its_scheme_word(self): + # An upstream scrub (MCP probe headers) leaves ``Digest ***``; the repr + # pass must not collapse that to a bare ``***`` and lose the scheme. + text = "headers={'Authorization': 'Digest ***'}" + assert redact_sensitive_text(text, force=True) == text + def test_code_file_preserves_secret_shaped_fixture(self): text = "CONFIG = {'BRAVE_API_KEY': 'fixture-value-1234567890'}" assert redact_sensitive_text(text, force=True, code_file=True) == text