Opened 2 years ago
Last modified 4 days ago
#35675 assigned Cleanup/optimization
Reduce impact of parsing crafted templates with repeat tags
| Reported by: | Jake Howard | Owned by: | Hailey Johnson |
|---|---|---|---|
| Component: | Template system | Version: | dev |
| Severity: | Normal | Keywords: | not-security |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | yes | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The template system uses a regex to extract template tags from text. Given certain inputs, this can take an excessive amount of time:
In [2]: %timeit Template("{%" * 2000) 34.7 ms ± 153 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) In [3]: %timeit Template("{%" * 10000) 877 ms ± 1.49 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) In [4]: %timeit Template("{%" * 20000) 3.49 s ± 47 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) In [5]: %timeit Template("{%") 11.5 µs ± 55.3 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
The cause is excessive backtracking in the pattern used. Since the template system is so versatile and performance-critical, fixing the issue appears non-trivial.
Note: This bug was raised with the Security Team prior to opening, however was not deemed a security vulnerability since parsing untrusted (or semi-trusted) templates is explicitly warned against.
Change History (8)
comment:1 by , 2 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|---|
| Type: | Bug → Cleanup/optimization |
| Version: | → dev |
comment:2 by , 2 years ago
Can't we use precompiling a regex pattern to enhance performance by avoiding repeated compilation overhead for frequent matches?
comment:3 by , 2 years ago
Can't we use precompiling a regex pattern
No, this regex is already compiled before execution (see the linked code above). Repeat compiling isn't the performance hit here, it's the backtracking in the pattern itself.
comment:4 by , 20 months ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:5 by , 19 months ago
| Has patch: | set |
|---|
comment:6 by , 18 months ago
| Needs tests: | set |
|---|
comment:7 by , 4 days ago
It may not be an "acceptance requirement" to fix the following, given its limited application, but I did want to mention the following finding after 1a9fba7a6c2a0acead19bbb45c25ceb0fdcca7c8, in case someone wants to look into it as well:
Matching can become quadratic when a long verbatim name contains repeated {% endverbatim sequences and the block body repeats those sequences without completing the expected closing tag:
{% verbatim {% endverbatim {% endverbatim finish %}
{% endverbatim {% endverbatim {% endverbatim {% endverbatim %}
The block’s name is {% endverbatim {% endverbatim finish. Each {% endverbatim in the body starts a potential match that eventually fails because finish is missing.
comment:8 by , 4 days ago
| Keywords: | not-security added |
|---|
Thank you Jake for taking the time to create this report. Accepting following the conversation within the Security Team.