mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-08 13:12:08 +00:00
fix(redact): skip env-lookup exception for JSON/YAML config field redaction
_redact_env already skips redaction when a KEY=value assignment's value is a programmatic env lookup (os.getenv(...), os.environ[...], process.env.X) per issue #2852 — masking it would corrupt a code snippet, not redact a secret. _redact_json (JSON "key": "value" syntax) and _redact_yaml (unquoted key: value syntax) are separate closures in the same function and never got the same check, so the identical code-snippet-in-config- syntax case still gets mangled: {"apiKey": "os.getenv('OPENAI_API_KEY')"} -> {"apiKey": "os.get...EY')"} api_key: os.getenv("OPENAI_API_KEY") -> api_key: os.get...EY") Fix: apply the same _ENV_LOOKUP_VALUE_RE.match(value) check in both closures before masking, mirroring _redact_env exactly. Real secret values in JSON/YAML syntax are still redacted (verified live and via new tests) — this only skips the case where the "value" already look like a code snippet.
This commit is contained in:
parent
2e2212be1b
commit
a573066543
2 changed files with 38 additions and 0 deletions
|
|
@ -570,6 +570,11 @@ def redact_sensitive_text(
|
|||
if ":" in text and '"' in text:
|
||||
def _redact_json(m):
|
||||
key, value = m.group(1), m.group(2)
|
||||
# Same programmatic-env-lookup exception as _redact_env above
|
||||
# (issue #2852): "apiKey": "os.getenv('X')" is a code snippet,
|
||||
# not a leaked secret value.
|
||||
if _ENV_LOOKUP_VALUE_RE.match(value):
|
||||
return m.group(0)
|
||||
return f'{key}: "{_mask_token(value)}"'
|
||||
text = _JSON_FIELD_RE.sub(_redact_json, text)
|
||||
|
||||
|
|
@ -579,6 +584,11 @@ def redact_sensitive_text(
|
|||
if ":" in text and "://" not in text:
|
||||
def _redact_yaml(m):
|
||||
key, sep, value = m.group(1), m.group(2), m.group(3)
|
||||
# Same programmatic-env-lookup exception as _redact_env above
|
||||
# (issue #2852): api_key: os.getenv('X') is a code snippet,
|
||||
# not a leaked secret value.
|
||||
if _ENV_LOOKUP_VALUE_RE.match(value):
|
||||
return m.group(0)
|
||||
return f"{key}{sep}{_mask_token(value)}"
|
||||
text = _YAML_ASSIGN_RE.sub(_redact_yaml, text)
|
||||
|
||||
|
|
|
|||
|
|
@ -185,6 +185,34 @@ class TestEnvLookupPreserved:
|
|||
result = redact_sensitive_text(text, force=True)
|
||||
assert "os.getenv('HOMEASSISTANT_TOKEN')" in result
|
||||
|
||||
def test_json_field_os_getenv_preserved(self):
|
||||
# _redact_env has the env-lookup exception; _redact_json (a separate
|
||||
# closure, JSON key: "value" syntax) did not, and mangled this into
|
||||
# '"apiKey": "os.get...EY')"'.
|
||||
text = '{"apiKey": "os.getenv(\'OPENAI_API_KEY\')"}'
|
||||
assert redact_sensitive_text(text, force=True) == text
|
||||
|
||||
def test_json_field_os_environ_get_preserved(self):
|
||||
text = '{"token": "os.environ.get(\'MY_TOKEN\')"}'
|
||||
assert redact_sensitive_text(text, force=True) == text
|
||||
|
||||
def test_json_field_real_value_still_redacted(self):
|
||||
text = '{"apiKey": "sk-realSecretValue1234567890"}'
|
||||
result = redact_sensitive_text(text, force=True)
|
||||
assert "sk-realSecretValue1234567890" not in result
|
||||
|
||||
def test_yaml_field_os_getenv_preserved(self):
|
||||
# Same exception missing from _redact_yaml (unquoted key: value
|
||||
# syntax) — mangled 'api_key: os.getenv("OPENAI_API_KEY")' into
|
||||
# 'api_key: os.get...EY")'.
|
||||
text = 'api_key: os.getenv("OPENAI_API_KEY")'
|
||||
assert redact_sensitive_text(text, force=True) == text
|
||||
|
||||
def test_yaml_field_real_value_still_redacted(self):
|
||||
text = "api_key: sk-realSecretValue1234567890"
|
||||
result = redact_sensitive_text(text, force=True)
|
||||
assert "sk-realSecretValue1234567890" not in result
|
||||
|
||||
|
||||
class TestJsonFields:
|
||||
def test_json_api_key(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue