Skip to content

Commit 8e280fd

Browse files
authored
Merge pull request from GHSA-wj85-w4f4-xh8h (#1350)
* ReDos: Apply `re.escape` to unsafe variable `keyword` before passing to `re.compile` * Replace ReDos-vulnerable regex with the one from upstream Python-Markdown * ReDos backtracking fix for macro plugin * Add release note for GHSA-wj85-w4f4-xh8h * Bump release date * Bump version
1 parent f7739d0 commit 8e280fd

File tree

5 files changed

+35
-10
lines changed

5 files changed

+35
-10
lines changed

Diff for: docs/release_notes.rst

+11
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ Removed
6868
* Removes support for Python 3.7, 3.8, 3.9
6969

7070

71+
0.10.1
72+
------
73+
74+
Released on 2024-03-16
75+
76+
Security
77+
~~~~~~~~
78+
79+
* Fixes reDOS issues: Denial of Service possible through unsafe regular expressions `GHSA-wj85-w4f4-xh8h <https://github.com/django-wiki/django-wiki/security/advisories/GHSA-wj85-w4f4-xh8h>`__ (Santos Gallegos, Benjamin Balder Bach)
80+
81+
7182
0.10
7283
----
7384

Diff for: src/wiki/core/markdown/mdx/codehilite.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from textwrap import dedent
2+
13
import logging
24
import re
35

@@ -7,6 +9,7 @@
79
from markdown.treeprocessors import Treeprocessor
810
from wiki.core.markdown import add_to_registry
911

12+
1013
logger = logging.getLogger(__name__)
1114

1215

@@ -35,14 +38,17 @@ class WikiFencedBlockPreprocessor(Preprocessor):
3538
"""
3639

3740
FENCED_BLOCK_RE = re.compile(
38-
r"""
39-
(?P<fence>^(?:~{3,}|`{3,}))[ ]* # Opening ``` or ~~~
40-
(\{?\.?(?P<lang>[a-zA-Z0-9_+-]*))?[ ]* # Optional {, and lang
41-
# Optional highlight lines, single- or double-quote-delimited
42-
(hl_lines=(?P<quot>"|')(?P<hl_lines>.*?)(?P=quot))?[ ]*
43-
}?[ ]*\n # Optional closing }
44-
(?P<code>.*?)(?<=\n)
45-
(?P=fence)[ ]*$""",
41+
dedent(
42+
r"""
43+
(?P<fence>^(?:~{3,}|`{3,}))[ ]* # opening fence
44+
((\{(?P<attrs>[^\}\n]*)\})| # (optional {attrs} or
45+
(\.?(?P<lang>[\w#.+-]*)[ ]*)? # optional (.)lang
46+
(hl_lines=(?P<quot>"|')(?P<hl_lines>.*?)(?P=quot)[ ]*)?) # optional hl_lines)
47+
\n # newline (end of opening fence)
48+
(?P<code>.*?)(?<=\n) # the code block
49+
(?P=fence)[ ]*$ # closing fence
50+
"""
51+
),
4652
re.MULTILINE | re.DOTALL | re.VERBOSE,
4753
)
4854
CODE_WRAP = "<pre>%s</pre>"

Diff for: src/wiki/plugins/macros/mdx/macro.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
# http://stackoverflow.com/questions/430759/regex-for-managing-escaped-characters-for-items-like-string-literals
1212
re_sq_short = r"'([^'\\]*(?:\\.[^'\\]*)*)'"
1313

14-
MACRO_RE = r"(\[(?P<macro>\w+)(?P<kwargs>\s\w+\:.+)*\])"
14+
15+
MACRO_RE = (
16+
r"""\[(?P<macro>\w+)(?P<kwargs>(\s+\w+\:([^\:\]\s]+|'[^']+'))+)*\]"""
17+
)
18+
1519
KWARG_RE = re.compile(
1620
r"\s*(?P<arg>\w+)(:(?P<value>([^\']+|%s)))?" % re_sq_short, re.IGNORECASE
1721
)
@@ -48,10 +52,12 @@ def handleMatch(self, m):
4852
kwargs = m.group("kwargs")
4953
if not kwargs:
5054
return getattr(self, macro)()
55+
5156
kwargs_dict = {}
5257
for kwarg in KWARG_RE.finditer(kwargs):
5358
arg = kwarg.group("arg")
5459
value = kwarg.group("value")
60+
5561
if value is None:
5662
value = True
5763
if isinstance(value, str):

Diff for: src/wiki/templatetags/wiki_tags.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def clean_text(content):
129129
before = " ".join(before_words)
130130
after = " ".join(after_words)
131131
html = ("%s %s %s" % (before, striptags(match), after)).strip()
132-
kw_p = re.compile(r"(\S*%s\S*)" % keyword, re.IGNORECASE)
132+
kw_p = re.compile(r"(\S*%s\S*)" % re.escape(keyword), re.IGNORECASE)
133133
html = kw_p.sub(r"<strong>\1</strong>", html)
134134

135135
return mark_safe(html)

Diff for: tests/plugins/macros/test_toc.py

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99

1010
class TocMacroTests(TestCase):
11+
maxDiff = None
12+
1113
def test_toc_renders_table_of_content(self):
1214
"""Verifies that the [TOC] wiki code renders a Table of Content"""
1315
md = Markdown(extensions=["extra", WikiTocExtension()])

0 commit comments

Comments
 (0)