CVE-2021-32837 (published 2023-01-17T22:15Z)

mechanize, a library for automatically interacting with HTTP web servers, contains a regular expression that is vulnerable to regular expression denial of service (ReDoS) prior to version 0.4.6. If a web server responds in a malicious way, then mechanize could crash. Version 0.4.6 has a patch for the issue.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-1333
cwe_name: Inefficient Regular Expression Complexity
description: The product uses a regular expression with an inefficient, possibly exponential worst-case computational complexity that consumes excessive CPU cycles.
extended_description: Some regular expression engines have a feature called "backtracking". If the token cannot match, the engine "backtracks" to a position that may result in a different token that can match.
                Backtracking becomes a weakness if all of these conditions are met:
                
                    The number of possible backtracking attempts are exponential relative to the length of the input.
                    The input can fail to match the regular expression.
                    The input can be long enough.
                
		
		  Attackers can create crafted inputs that
		  intentionally cause the regular expression to use
		  excessive backtracking in a way that causes the CPU
		  consumption to spike.
		
            
            

Fix information:
repo_url: https://github.com/python-mechanize/mechanize
commit_details: repo_url: https://github.com/python-mechanize/mechanize
author: Kovid Goyal
author_date: 2021-08-31 19:27:23+05:30
msg: Use the current upstream (python3.9) authreq header parsing regex

Fixes a DoS when parsing a malformed auth header. Reported by CodeQL.
Reference GHSL-2021-108
repository: repo_url: https://github.com/python-mechanize/mechanize
repo_name: python-mechanize/mechanize
description: The official source code for the python-mechanize project
repo_language: Python
owner: python-mechanize
file_changes: filename: _urllib2_fork.py
change_type: ModificationType.MODIFY
diff: @@ -875,8 +875,15 @@ class AbstractBasicAuthHandler:
 
     # allow for double- and single-quoted realm values
     # (single quotes are a violation of the RFC, but appear in the wild)
-    rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
-                    'realm=(["\'])(.*?)\\2', re.I)
+    rx = re.compile('(?:^|,)'     # start of the string or ','
+                    '[ \t]*'      # optional whitespaces
+                    '([^ \t,]+)'  # scheme like "Basic"
+                    '[ \t]+'      # mandatory whitespaces
+                    # realm=xxx
+                    # realm='xxx'
+                    # realm="xxx"
+                    'realm=(["\']?)([^"\']*)\\2',
+                    re.I)
 
     # XXX could pre-emptively send auth info already accepted (RFC 2617,
     # end of section 2, and section 1.2 immediately after "credentials"

programming_language: Python
filename: test_urllib2.py
change_type: ModificationType.MODIFY
diff: @@ -24,7 +24,7 @@ from mechanize import HTTPRedirectHandler, \
     HTTPCookieProcessor, HTTPRefererProcessor, \
     HTTPErrorProcessor, HTTPHandler
 from mechanize import OpenerDirector, build_opener, Request
-from mechanize._urllib2_fork import AbstractHTTPHandler, normalize_url
+from mechanize._urllib2_fork import AbstractHTTPHandler, normalize_url, AbstractBasicAuthHandler
 from mechanize._util import write_file
 
 import mechanize._response
@@ -69,6 +69,10 @@ class TrivialTests(mechanize._testcase.TestCase):
             self.assertEqual(
                 mechanize._urllib2_fork.parse_http_list(string), list)
 
+    def test_parse_authreq(self):
+        for bad in (",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",):
+            self.assertIsNone(AbstractBasicAuthHandler.rx.search(bad))
+
 
 def test_request_headers_dict():
     """

programming_language: Python