summaryrefslogtreecommitdiffstats
path: root/Lib/http
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-08-17 13:30:52 (GMT)
committerGitHub <noreply@github.com>2024-08-17 13:30:52 (GMT)
commit44e458357fca05ca0ae2658d62c8c595b048b5ef (patch)
tree768f7f526ee50f37b70b8545891b27b0496c4117 /Lib/http
parentd60b97a833fd3284f2ee249d32c97fc359d83486 (diff)
downloadcpython-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.py34
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