[3.12] gh-146333: Fix quadratic regex backtracking in configparser option parsing (GH-146399) (GH-148559) (#154081)
Yhg1s <[email protected]> Tue, 04 Aug 2026 05:31:29 -0400 (EDT)
| Newsgroups | gmane.comp.python.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://github.com/python/cpython/commit/57558307909b703f669437594778c7482671a3a5 commit: 57558307909b703f669437594778c7482671a3a5 branch: 3.12 author: Petr Viktorin <[email protected]> committer: Yhg1s <[email protected]> date: 2026-08-04T11:29:49+02:00 summary: [3.12] gh-146333: Fix quadratic regex backtracking in configparser option parsing (GH-146399) (GH-148559) (#154081) Use negative lookahead in option regex to prevent backtracking, and to avoid changing logic outside the regexes (since people could use the regex directly). (cherry picked from commit 7e0a0be4097f9d29d66fe23f5af86f18a34ed7dd) (cherry picked from commit a5969e8f0fda37aaf0e2f844fdcfca9d822a70b1) Co-authored-by: Joshua Swanson <[email protected]> files: A Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst M Lib/configparser.py M Lib/test/test_configparser.py diff --git a/Lib/configparser.py b/Lib/configparser.py index 8ae35a0a1893b4..14f30d6c124edd 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -548,7 +548,9 @@ class RawConfigParser(MutableMapping): \] # ] """ _OPT_TMPL = r""" - (?P<option>.*?) # very permissive! + (?P<option> # very permissive! + (?:(?!{delim})\S)* # non-delimiter non-whitespace + (?:\s+(?:(?!{delim})\S)+)*) # optionally more words \s*(?P<vi>{delim})\s* # any number of space/tab, # followed by any of the # allowed delimiters, @@ -556,7 +558,9 @@ class RawConfigParser(MutableMapping): (?P<value>.*)$ # everything up to eol """ _OPT_NV_TMPL = r""" - (?P<option>.*?) # very permissive! + (?P<option> # very permissive! + (?:(?!{delim})\S)* # non-delimiter non-whitespace + (?:\s+(?:(?!{delim})\S)+)*) # optionally more words \s*(?: # any number of space/tab, (?P<vi>{delim})\s* # optionally followed by # any of the allowed diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 389aa15e67009a..8cf5d2d50dc1a3 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -2144,6 +2144,26 @@ def test_instance_assignment(self): self.assertEqual(cfg['two'].getlen('one'), 5) +class ReDoSTestCase(unittest.TestCase): + """Regression tests for quadratic regex backtracking (gh-146333).""" + + def test_option_regex_does_not_backtrack(self): + # A line with many spaces between non-delimiter characters + # should be parsed in linear time, not quadratic. + parser = configparser.RawConfigParser() + content = "[section]\n" + "x" + " " * 40000 + "y" + "\n" + # This should complete almost instantly. Before the fix, + # it would take over a minute due to catastrophic backtracking. + with self.assertRaises(configparser.ParsingError): + parser.read_string(content) + + def test_option_regex_no_value_does_not_backtrack(self): + parser = configparser.RawConfigParser(allow_no_value=True) + content = "[section]\n" + "x" + " " * 40000 + "y" + "\n" + parser.read_string(content) + self.assertTrue(parser.has_option("section", "x" + " " * 40000 + "y")) + + class MiscTestCase(unittest.TestCase): def test__all__(self): support.check__all__(self, configparser, not_exported={"Error"}) diff --git a/Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst b/Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst new file mode 100644 index 00000000000000..96d86ecc0a0fb3 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst @@ -0,0 +1,3 @@ +Fix quadratic backtracking in :class:`configparser.RawConfigParser` option +parsing regexes (``OPTCRE`` and ``OPTCRE_NV``). A crafted configuration line +with many whitespace characters could cause excessive CPU usage. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]