diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2024-08-17 13:30:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-17 13:30:52 (GMT) |
commit | 44e458357fca05ca0ae2658d62c8c595b048b5ef (patch) | |
tree | 768f7f526ee50f37b70b8545891b27b0496c4117 /Lib/http | |
parent | d60b97a833fd3284f2ee249d32c97fc359d83486 (diff) | |
download | cpython-44e458357fca05ca0ae2658d62c8c595b048b5ef.zip cpython-44e458357fca05ca0ae2658d62c8c595b048b5ef.tar.gz cpython-44e458357fca05ca0ae2658d62c8c595b048b5ef.tar.bz2 |
gh-123067: Fix quadratic complexity in parsing "-quoted cookie values with backslashes (GH-123075)
This fixes CVE-2024-7592.
Diffstat (limited to 'Lib/http')
-rw-r--r-- | Lib/http/cookies.py | 34 |
1 files changed, 8 insertions, 26 deletions
diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index 351faf4..6b9ed24 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -184,8 +184,13 @@ def _quote(str): return '"' + str.translate(_Translator) + '"' -_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]") -_QuotePatt = re.compile(r"[\\].") +_unquote_sub = re.compile(r'\\(?:([0-3][0-7][0-7])|(.))').sub + +def _unquote_replace(m): + if m[1]: + return chr(int(m[1], 8)) + else: + return m[2] def _unquote(str): # If there aren't any doublequotes, @@ -205,30 +210,7 @@ def _unquote(str): # \012 --> \n # \" --> " # - i = 0 - n = len(str) - res = [] - while 0 <= i < n: - o_match = _OctalPatt.search(str, i) - q_match = _QuotePatt.search(str, i) - if not o_match and not q_match: # Neither matched - res.append(str[i:]) - break - # else: - j = k = -1 - if o_match: - j = o_match.start(0) - if q_match: - k = q_match.start(0) - if q_match and (not o_match or k < j): # QuotePatt matched - res.append(str[i:k]) - res.append(str[k+1]) - i = k + 2 - else: # OctalPatt matched - res.append(str[i:j]) - res.append(chr(int(str[j+1:j+4], 8))) - i = j + 4 - return _nulljoin(res) + return _unquote_sub(_unquote_replace, str) # The _getdate() routine is used to set the expiration time in the cookie's HTTP # header. By default, _getdate() returns the current time in the appropriate |