CVE-2021-26813
Description
markdown2 before 2.4.0 is vulnerable to regular expression denial of service (ReDoS) via crafted input causing catastrophic backtracking.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
markdown2 before 2.4.0 is vulnerable to regular expression denial of service (ReDoS) via crafted input causing catastrophic backtracking.
Root
Cause The python-markdown2 library (versions >= 1.0.1.18) contains multiple vulnerable regular expressions in markdown2.py that are susceptible to catastrophic backtracking. These patterns are used when certain extras (such as 'numbering' or 'fenced-code-blocks') are enabled. For example, the regex for numbered definitions (self.regex_defns) includes repeating groups that match spaces, leading to cubic time complexity on long strings of spaces [3].
Exploitation
An attacker can provide a specially crafted string as markdown input. No authentication or special privileges are required if the application processes user-supplied markdown. The attack is triggered by sending a string that includes a large number of repeating characters (e.g., spaces or newlines) that cause the regex engine to stall. This can be done remotely over the network [1].
Impact
Successful exploitation results in a denial of service condition. The processing of markdown becomes extremely slow or effectively hangs, consuming excessive CPU resources. This can disrupt the availability of the application using markdown2 [1][2].
Mitigation
The vulnerability is fixed in markdown2 version 2.4.0. Users should upgrade to this version or later to avoid the ReDoS issue. No workarounds are available for affected versions [1][3].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
markdown2PyPI | >= 1.0.1.18, < 2.4.0 | 2.4.0 |
Affected products
5- markdown2/markdown2description
- ghsa-coords4 versionspkg:pypi/markdown2pkg:rpm/opensuse/python-markdown2&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/python-markdown2&distro=openSUSE%20Tumbleweedpkg:rpm/suse/python-markdown2&distro=SUSE%20Package%20Hub%2015%20SP2
>= 1.0.1.18, < 2.4.0+ 3 more
- (no CPE)range: >= 1.0.1.18, < 2.4.0
- (no CPE)range: < 2.4.0-lp152.2.3.1
- (no CPE)range: < 2.4.0-2.4
- (no CPE)range: < 2.4.0-bp152.2.4.1
Patches
17b6512607396Merge pull request #387 from trentm/regex-dos
1 file changed · +7 −7
lib/markdown2.py+7 −7 modified@@ -532,7 +532,7 @@ def parse_structured_value(value): return tail - _emacs_oneliner_vars_pat = re.compile(r"-\*-\s*([^\r\n]*?)\s*-\*-", re.UNICODE) + _emacs_oneliner_vars_pat = re.compile(r"-\*-\s*(?:(\S[^\r\n]*?)([\r\n]\s*)?)?-\*-", re.UNICODE) # This regular expression is intended to match blocks like this: # PREFIX Local Variables: SUFFIX # PREFIX mode: Tcl SUFFIX @@ -892,8 +892,8 @@ def _do_numbering(self, text): ''' # First pass to define all the references self.regex_defns = re.compile(r''' - \[\#(\w+)\s* # the counter. Open square plus hash plus a word \1 - ([^@]*)\s* # Some optional characters, that aren't an @. \2 + \[\#(\w+) # the counter. Open square plus hash plus a word \1 + ([^@]*) # Some optional characters, that aren't an @. \2 @(\w+) # the id. Should this be normed? \3 ([^\]]*)\] # The rest of the text up to the terminating ] \4 ''', re.VERBOSE) @@ -908,7 +908,7 @@ def _do_numbering(self, text): if len(match.groups()) != 4: continue counter = match.group(1) - text_before = match.group(2) + text_before = match.group(2).strip() ref_id = match.group(3) text_after = match.group(4) number = counters.get(counter, 1) @@ -1926,9 +1926,9 @@ def _do_code_blocks(self, text): _fenced_code_block_re = re.compile(r''' (?:\n+|\A\n?) - ^```\s*?([\w+-]+)?\s*?\n # opening fence, $1 = optional lang - (.*?) # $2 = code block content - ^```[ \t]*\n # closing fence + ^```\s{0,99}([\w+-]+)?\s{0,99}\n # opening fence, $1 = optional lang + (.*?) # $2 = code block content + ^```[ \t]*\n # closing fence ''', re.M | re.X | re.S) def _fenced_code_block_sub(self, match):
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- github.com/advisories/GHSA-jr9p-r423-9m2rghsaADVISORY
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/BRP5RN35JZTSJ3JT4722F447ZDK7LZS5/mitrevendor-advisoryx_refsource_FEDORA
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/J752422YELXLMLZJPVJVKD2KKHHQRVEH/mitrevendor-advisoryx_refsource_FEDORA
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/JTIX5UXRDJZJ57DO4V33ZNJTNKWGBQLY/mitrevendor-advisoryx_refsource_FEDORA
- nvd.nist.gov/vuln/detail/CVE-2021-26813ghsaADVISORY
- github.com/pypa/advisory-database/tree/main/vulns/markdown2/PYSEC-2021-20.yamlghsaWEB
- github.com/trentm/python-markdown2/commit/7b651260739647de5198323e0445b1618750c374ghsaWEB
- github.com/trentm/python-markdown2/pull/387ghsax_refsource_MISCWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/BRP5RN35JZTSJ3JT4722F447ZDK7LZS5ghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/J752422YELXLMLZJPVJVKD2KKHHQRVEHghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/JTIX5UXRDJZJ57DO4V33ZNJTNKWGBQLYghsaWEB
News mentions
0No linked articles in our index yet.