Skip to content

Commit a799a92

Browse files
author
luigi liu
authored
Apply redaction replacement strings literally
1 parent 601a5f9 commit a799a92

2 files changed

Lines changed: 28 additions & 10 deletions

File tree

‎awscli/redaction.py‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,23 @@ def register_redaction(pattern, replacement):
2626
:param pattern: The regular expression to match sensitive text with.
2727
2828
:type replacement: str or callable
29-
:param replacement: The text to replace each match with, or a function
30-
that takes the match object and returns the replacement text.
29+
:param replacement: The literal text to replace each match with, or a
30+
function that takes the match object and returns the replacement
31+
text.
32+
33+
Patterns are applied in registration order, so a pattern also sees the
34+
replacements made by patterns registered before it.
3135
"""
3236
if isinstance(pattern, str):
3337
pattern = re.compile(pattern)
38+
if not callable(replacement):
39+
text = replacement
40+
41+
# A function's return value is used as is, whereas re.sub would
42+
# interpret backslashes in a replacement string as escapes.
43+
def replacement(match):
44+
return text
45+
3446
_REDACTIONS.append((pattern, replacement))
3547

3648

‎tests/unit/test_redaction.py‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def test_redacts_nested_values():
8080
[
8181
['cloudfront', 'sign', '--private-key', 'file://key.pem'],
8282
'{"a": "-----BEGIN PUBLIC KEY-----"}',
83-
'{"Certificate": "%s"}' % _b64(CERT_PEM),
83+
f'{{"Certificate": "{_b64(CERT_PEM)}"}}',
8484
{'headers': {'a': 'b'}, 'body': b'\xff\xfe'},
8585
None,
8686
object(),
@@ -92,13 +92,10 @@ def test_returns_values_without_matches_unchanged(value):
9292

9393
@pytest.mark.parametrize('pem', [KEY_PEM, CERT_PEM + KEY_PEM])
9494
def test_redacts_base64_private_keys(pem):
95-
value = '{"Certificate": "%s", "PrivateKey": "%s"}' % (
96-
_b64(CERT_PEM),
97-
_b64(pem),
98-
)
99-
assert redact(value) == '{"Certificate": "%s", "PrivateKey": "%s"}' % (
100-
_b64(CERT_PEM),
101-
REDACTED,
95+
cert = _b64(CERT_PEM)
96+
value = f'{{"Certificate": "{cert}", "PrivateKey": "{_b64(pem)}"}}'
97+
assert redact(value) == (
98+
f'{{"Certificate": "{cert}", "PrivateKey": "{REDACTED}"}}'
10299
)
103100

104101

@@ -117,3 +114,12 @@ def test_register_redaction(monkeypatch):
117114
monkeypatch.setattr(redaction, '_REDACTIONS', list(redaction._REDACTIONS))
118115
register_redaction(r'secret-\w+', '<redacted secret>')
119116
assert redact(['a secret-abc123']) == ['a <redacted secret>']
117+
118+
119+
@pytest.mark.parametrize('replacement', [r'\1', r'C:\x', r'C:\new'])
120+
def test_register_redaction_uses_replacement_literally(
121+
monkeypatch, replacement
122+
):
123+
monkeypatch.setattr(redaction, '_REDACTIONS', list(redaction._REDACTIONS))
124+
register_redaction(r'secret-\w+', replacement)
125+
assert redact('a secret-abc123') == 'a ' + replacement

0 commit comments

Comments
 (0)