You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2dd5a06
Browse filesBrowse the repository at this point in the historyBrowse files
fix(security): address third-round Copilot review on #5053 - stale warning text, args aliasing, a key.lower() crash, numeric redact_strings, and overlap labels
Five suppressed findings from the latest Copilot review of the #4770 write-time
log redaction PR, all confirmed and fixed.
Warning text contradicted the actual (already-fixed) behaviour
------------------------------------------------------------------
The scalar_value_dict warning told the user to quote a numeric value "to
ensure it is matched", but collect_log_secret_values() already coerces it to
a string regardless. Reworded to explain the real reason to quote it: keeping
exact formatting (a leading zero, say) rather than losing it to numeric
parsing.
A test restored my_predbat.args by reassignment, not in place
------------------------------------------------------------------
ComponentBase.__init__ aliases self.args = base.args at construction, so a
test that restores my_predbat.args = saved_args (rather than mutating the
same dict object back to its original contents) leaves any component already
holding that reference pointing at the old, still-mutated dict - the test
itself looks clean but a component alias is not. Fixed both _run()'s shared
restore and the redact_strings_labelled numeric-value test's own restore to
clear()+update() in place. Confirmed the leak directly: with the old
reassignment restore, a stand-in "component alias" dict still carried the
test's added key after _run() returned; with the fix, it does not.
_collect_secret_values crashed on a non-string top-level dict key
------------------------------------------------------------------
The redact_strings/redact_strings_labelled exemption added for the
label-priority fix called key.lower() unconditionally. is_secret_key()
already tolerates a non-string key (str(key).lower()) for exactly this
reason - log() runs on the very first startup line, before validation has
had any chance to report a malformed apps.yaml. Matched the same guard.
Numeric redact_strings (bare list) values were still silently dropped
------------------------------------------------------------------------
The earlier fix coerced scalar secrets.yaml and redact_strings_labelled
values to string but missed the parallel redact_strings list form - an
unquoted numeric MPAN there (redact_strings: [1234567890123]) still failed
the isinstance(value, str) check and never reached the log redaction set.
An overlapping-secret mask lost its label
------------------------------------------------------------------------
redact_log_line()'s overlap-extension fix (previous commit) covered the full
extended span but looked its label up as labels.get(merged_span, ...) - the
merged span spanning more than one secret is not itself a key in labels, so
it silently fell back to the generic <xxx> mask, losing the "which
credential" guarantee a labelled mask exists to provide even though nothing
leaked. Now tracks the label of every secret that contributed to the
(possibly chained) extended span and joins them, e.g. <api_key+redact_strings>.
All five verified with mutation testing: reverting each fix in turn
reproduces exactly the failure its regression test describes, and only that
test fails.
./run_all --quick and ./run_pre_commit both green.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: apps/predbat/predbat.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1652,7 +1652,7 @@ def validate_config(self):
1652
1652
ifspec.get("scalar_value_dict", False):
1653
1653
forkey, sub_valueinitem.items():
1654
1654
ifnotisinstance(sub_value, str):
1655
-
self.log("Warn: Validation of apps.yaml found configuration item '{}' entry '{}' value {} is not a string - quote it to ensure it is matched".format(name, key, sub_value))
1655
+
self.log("Warn: Validation of apps.yaml found configuration item '{}' entry '{}' value {} is not a string - quote it to keep its exact formatting (e.g. a leading zero)".format(name, key, sub_value))
assert"redact_strings_labelled"notinmy_predbat.arg_errors, "a numeric redact_strings_labelled value should warn, not error: {}".format(my_predbat.arg_errors.get("redact_strings_labelled"))
214
219
assertany("my_mpan"inmsgand"not a string"inmsgformsgincaptured), "expected a 'not a string' warning naming my_mpan, got {}".format(captured)
215
220
finally:
216
-
my_predbat.args=saved_args
221
+
# In place, not reassignment - see _run()'s equivalent comment above (#5053 review).
0 commit comments