mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 12:53:26 +00:00
[core] Tighten legacy redaction regex to avoid mid-word matches
The trailing \w* after the fragment over-matched fields like key_value_pair: which the prior regex did not catch. Drop it so the fragment must end the captured field name, preserving the previous matching scope while still capturing the full field name (via the leading \w*) for the warning message.
This commit is contained in:
@@ -1427,9 +1427,12 @@ def command_config(args: ArgsProtocol, config: ConfigType) -> int | None:
|
||||
# in 2026.12.0 once canonical sensitive fields are migrated.
|
||||
#
|
||||
# The negative lookahead ``(?!\\033\[8m)`` skips values already wrapped by the
|
||||
# SensitiveStr representer, so explicit tagging silences the warning.
|
||||
# SensitiveStr representer, so explicit tagging silences the warning. No
|
||||
# trailing ``\w*`` after the fragment so the fragment must end the field
|
||||
# name (preserves the prior regex's matching scope while letting the
|
||||
# leading ``\w*`` capture the full field name for the warning).
|
||||
_LEGACY_REDACTION_RE = re.compile(
|
||||
r"(?P<key>\w*(?:password|key|psk|ssid)\w*)\: (?!\\033\[8m)(?P<val>.+)"
|
||||
r"(?P<key>\w*(?:password|key|psk|ssid))\: (?!\\033\[8m)(?P<val>.+)"
|
||||
)
|
||||
_LEGACY_REDACTION_REMOVAL = "2026.12.0"
|
||||
|
||||
|
||||
@@ -387,6 +387,18 @@ def test_redact_with_legacy_fallback__deduplicates_warnings(
|
||||
assert len(password_warnings) == 1
|
||||
|
||||
|
||||
def test_redact_with_legacy_fallback__does_not_match_fragment_in_middle(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Fragment must end the field name; embedded matches like
|
||||
``key_value_pair`` are unrelated to a sensitive key and must not be
|
||||
redacted (matching the prior regex's scope)."""
|
||||
with caplog.at_level(logging.WARNING, logger="esphome.__main__"):
|
||||
out = _redact_with_legacy_fallback("key_value_pair: abc\n")
|
||||
assert "\\033[8m" not in out
|
||||
assert not any("legacy substring" in rec.message for rec in caplog.records)
|
||||
|
||||
|
||||
def test_choose_upload_log_host_with_string_default() -> None:
|
||||
"""Test with a single string default device."""
|
||||
setup_core()
|
||||
|
||||
Reference in New Issue
Block a user