test(redact): add YAML ReDoS test, strengthen existing test with keyword
- Relax timing bound from 1.0s to 2.0s (CI machine robustness). - Add test_long_dotted_run_with_keyword_completes_fast: includes a secret keyword so the pre-gate does NOT skip _CFG_DOTTED_RE — directly exercises the possessive-quantifier regex, not just the pre-gate. - Add test_yaml_assign_redos_resistance: _YAML_ASSIGN_RE was modified but had no ReDoS test — add 100-line stress input. - Add test_yaml_assign_secret_still_redacted: verify YAML matching behavior preserved with possessive quantifiers.
This commit is contained in:
@@ -560,7 +560,22 @@ class TestConfigKeyRedosResistance:
|
||||
text = ".".join(["segment"] * 100) + " end"
|
||||
t0 = time.perf_counter()
|
||||
assert redact_sensitive_text(text) == text
|
||||
assert time.perf_counter() - t0 < 1.0
|
||||
assert time.perf_counter() - t0 < 2.0
|
||||
|
||||
def test_long_dotted_run_with_keyword_completes_fast(self):
|
||||
"""Exercise _CFG_DOTTED_RE directly (bypasses the keyword pre-gate).
|
||||
|
||||
The pre-gate skips the regex when no secret keyword is present, so
|
||||
test_long_dotted_run_completes_fast only guards the pre-gate. This
|
||||
test includes a keyword but no '=' so the regex runs and must still
|
||||
complete quickly thanks to the possessive quantifiers.
|
||||
"""
|
||||
import time
|
||||
|
||||
text = ".".join(["segment"] * 100) + ".token end"
|
||||
t0 = time.perf_counter()
|
||||
assert redact_sensitive_text(text) == text
|
||||
assert time.perf_counter() - t0 < 2.0
|
||||
|
||||
def test_long_dotted_secret_still_redacted(self):
|
||||
# Possessive quantifiers must not change matching behavior.
|
||||
@@ -569,6 +584,25 @@ class TestConfigKeyRedosResistance:
|
||||
assert "Sup3rS3cret!" not in result
|
||||
assert ".password=" in result
|
||||
|
||||
def test_yaml_assign_redos_resistance(self):
|
||||
"""_YAML_ASSIGN_RE must not backtrack excessively on long inputs."""
|
||||
import time
|
||||
|
||||
# 100 lines of a long dotted key with a secret keyword but no
|
||||
# matching colon-value form — stresses the regex without matching.
|
||||
line = "a." * 50 + "token not_an_assignment"
|
||||
text = "\n".join([line] * 100)
|
||||
t0 = time.perf_counter()
|
||||
redact_sensitive_text(text)
|
||||
assert time.perf_counter() - t0 < 2.0
|
||||
|
||||
def test_yaml_assign_secret_still_redacted(self):
|
||||
# Possessive quantifiers must not change YAML matching behavior.
|
||||
text = "spring.datasource.password: hunter2"
|
||||
result = redact_sensitive_text(text)
|
||||
assert "hunter2" not in result
|
||||
assert "password:" in result
|
||||
|
||||
|
||||
class TestXaiToken:
|
||||
KEY = "xai-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstu"
|
||||
|
||||
Reference in New Issue
Block a user