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
rule 941170 (NoScript InjectionChecker: Attribute Injection) shows a measurable PCRE performance regression in the v4 line vs v3.3 on benign inputs. the cause is a single sub-pattern change in the moz-binding alternation branch, introduced in PR #2292 (Nov 2021) and never backported to v3.3.
\W*?- → [^-]*?- — this is the regression source.\W matches only non-word chars; [^-] matches everything except - (including all word chars). combined with the outer (?:\W|^) start anchor (which retries at every non-word boundary) and the chained \W*? separators following it, the engine backtracks across a much larger search space on benign long inputs that contain a - somewhere.
[\s\S]*?:[\s\S]*? → [^:]*?: — this is not the regression; it's a small fail-fast improvement and should be kept.
PR #2292 has no description, no rationale, and no tests. the 941170 test file (tests/regression/tests/REQUEST-941-APPLICATION-ATTACK-XSS/941170.yaml) has zero tests covering the moz-binding sub-branch, so the change isn't load-bearing for any documented coverage.
measurements
PCRE benchmark via Perl, 200 iterations per long input:
input
v3.3
v4.25
regression
("a" x 2048) . "-x" (one dash near end)
0.046s
0.115s
2.5×
UA-like header w/ many dashes (840 B)
0.016s
0.026s
1.7×
query string w/ many dashes (2404 B)
0.048s
0.067s
1.4×
benign 4608 B w/ many dashes interleaved
0.096s
0.128s
1.3×
short benign / no-dash inputs
n/a
n/a
none
positive -moz-binding match
0.003s
0.003s
none
reproduction script available on request.
proposed fix
revert only the regression-introducing fragment ([^-]*?- → \W*?-), keep the [^:]*?: improvement:
restores v3.3 perf on every measured input, no regression on positive matches. the rule's transformation chain (utf8toUnicode, urlDecodeUni, htmlEntityDecode, jsDecode, cssDecode) already normalizes encoded variants, so \W*? is sufficient by the time the regex sees the input.
assisted with: regex diffing across versions, PCRE microbenchmark scaffolding, issue body drafting
review performed: manually verified diff between v3.3.9 and v4.25.0 rule files, ran the benchmark locally and confirmed numbers, cross-checked PR fix 941170 #2292 patch and absence of tests/description, confirmed test file has no moz-binding coverage
summary
rule 941170 (NoScript InjectionChecker: Attribute Injection) shows a measurable PCRE performance regression in the v4 line vs v3.3 on benign inputs. the cause is a single sub-pattern change in the moz-binding alternation branch, introduced in PR #2292 (Nov 2021) and never backported to v3.3.
affected versions
main/4.27.0-dev)root cause
the moz-binding branch of the rule's regex changed as follows:
\W*?-\W*?m\W*?o\W*?z\W*?-\W*?b\W*?i\W*?n\W*?d\W*?i\W*?n\W*?g[\s\S]*?:[\s\S]*?\W*?u\W*?r\W*?l[\s\S]*?\([^-]*?-\W*?m\W*?o\W*?z\W*?-\W*?b\W*?i\W*?n\W*?d\W*?i\W*?n\W*?g[^:]*?:\W*?u\W*?r\W*?l[\s\S]*?\(two changes were made:
\W*?-→[^-]*?-— this is the regression source.\Wmatches only non-word chars;[^-]matches everything except-(including all word chars). combined with the outer(?:\W|^)start anchor (which retries at every non-word boundary) and the chained\W*?separators following it, the engine backtracks across a much larger search space on benign long inputs that contain a-somewhere.[\s\S]*?:[\s\S]*?→[^:]*?:— this is not the regression; it's a small fail-fast improvement and should be kept.PR #2292 has no description, no rationale, and no tests. the 941170 test file (
tests/regression/tests/REQUEST-941-APPLICATION-ATTACK-XSS/941170.yaml) has zero tests covering the moz-binding sub-branch, so the change isn't load-bearing for any documented coverage.measurements
PCRE benchmark via Perl, 200 iterations per long input:
("a" x 2048) . "-x"(one dash near end)-moz-bindingmatchreproduction script available on request.
proposed fix
revert only the regression-introducing fragment (
[^-]*?-→\W*?-), keep the[^:]*?:improvement:restores v3.3 perf on every measured input, no regression on positive matches. the rule's transformation chain (
utf8toUnicode,urlDecodeUni,htmlEntityDecode,jsDecode,cssDecode) already normalizes encoded variants, so\W*?is sufficient by the time the regex sees the input.refs
.raconversion branch (not yet merged): commits 7f1b160, af2da18ai disclosure