57bb731638
Addresses CVE-2020-27619, CVE-2021-3177, CVE-2021-3733, CVE-2021-3737 and CVE-2021-23336. Patches mostly sourced via Fedora.
128 lines
5.5 KiB
Python
128 lines
5.5 KiB
Python
$NetBSD: patch-Lib_cgi.py,v 1.1 2021/10/10 03:00:59 gutteridge Exp $
|
|
|
|
Fix CVE-2021-23336: Add `separator` argument to parse_qs; warn with default
|
|
Via Fedora:
|
|
https://src.fedoraproject.org/rpms/python2.7/blob/rawhide/f/00359-CVE-2021-23336.patch
|
|
|
|
--- Lib/cgi.py.orig 2020-04-19 21:13:39.000000000 +0000
|
|
+++ Lib/cgi.py
|
|
@@ -121,7 +121,8 @@ log = initlog # The current lo
|
|
# 0 ==> unlimited input
|
|
maxlen = 0
|
|
|
|
-def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
|
|
+def parse(fp=None, environ=os.environ, keep_blank_values=0,
|
|
+ strict_parsing=0, separator=None):
|
|
"""Parse a query in the environment or from a file (default stdin)
|
|
|
|
Arguments, all optional:
|
|
@@ -140,6 +141,8 @@ def parse(fp=None, environ=os.environ, k
|
|
strict_parsing: flag indicating what to do with parsing errors.
|
|
If false (the default), errors are silently ignored.
|
|
If true, errors raise a ValueError exception.
|
|
+
|
|
+ separator: str. The symbol to use for separating the query arguments.
|
|
"""
|
|
if fp is None:
|
|
fp = sys.stdin
|
|
@@ -171,25 +174,26 @@ def parse(fp=None, environ=os.environ, k
|
|
else:
|
|
qs = ""
|
|
environ['QUERY_STRING'] = qs # XXX Shouldn't, really
|
|
- return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
|
|
+ return urlparse.parse_qs(qs, keep_blank_values, strict_parsing, separator=separator)
|
|
|
|
|
|
# parse query string function called from urlparse,
|
|
# this is done in order to maintain backward compatibility.
|
|
|
|
-def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
|
|
+def parse_qs(qs, keep_blank_values=0, strict_parsing=0, separator=None):
|
|
"""Parse a query given as a string argument."""
|
|
warn("cgi.parse_qs is deprecated, use urlparse.parse_qs instead",
|
|
PendingDeprecationWarning, 2)
|
|
- return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
|
|
+ return urlparse.parse_qs(qs, keep_blank_values, strict_parsing,
|
|
+ separator=separator)
|
|
|
|
|
|
-def parse_qsl(qs, keep_blank_values=0, strict_parsing=0, max_num_fields=None):
|
|
+def parse_qsl(qs, keep_blank_values=0, strict_parsing=0, max_num_fields=None, separator=None):
|
|
"""Parse a query given as a string argument."""
|
|
warn("cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead",
|
|
PendingDeprecationWarning, 2)
|
|
return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing,
|
|
- max_num_fields)
|
|
+ max_num_fields, separator=separator)
|
|
|
|
def parse_multipart(fp, pdict):
|
|
"""Parse multipart input.
|
|
@@ -288,7 +292,6 @@ def parse_multipart(fp, pdict):
|
|
|
|
return partdict
|
|
|
|
-
|
|
def _parseparam(s):
|
|
while s[:1] == ';':
|
|
s = s[1:]
|
|
@@ -395,7 +398,7 @@ class FieldStorage:
|
|
|
|
def __init__(self, fp=None, headers=None, outerboundary="",
|
|
environ=os.environ, keep_blank_values=0, strict_parsing=0,
|
|
- max_num_fields=None):
|
|
+ max_num_fields=None, separator=None):
|
|
"""Constructor. Read multipart/* until last part.
|
|
|
|
Arguments, all optional:
|
|
@@ -430,6 +433,7 @@ class FieldStorage:
|
|
self.keep_blank_values = keep_blank_values
|
|
self.strict_parsing = strict_parsing
|
|
self.max_num_fields = max_num_fields
|
|
+ self.separator = separator
|
|
if 'REQUEST_METHOD' in environ:
|
|
method = environ['REQUEST_METHOD'].upper()
|
|
self.qs_on_post = None
|
|
@@ -613,7 +617,8 @@ class FieldStorage:
|
|
if self.qs_on_post:
|
|
qs += '&' + self.qs_on_post
|
|
query = urlparse.parse_qsl(qs, self.keep_blank_values,
|
|
- self.strict_parsing, self.max_num_fields)
|
|
+ self.strict_parsing, self.max_num_fields,
|
|
+ self.separator)
|
|
self.list = [MiniFieldStorage(key, value) for key, value in query]
|
|
self.skip_lines()
|
|
|
|
@@ -629,7 +634,8 @@ class FieldStorage:
|
|
query = urlparse.parse_qsl(self.qs_on_post,
|
|
self.keep_blank_values,
|
|
self.strict_parsing,
|
|
- self.max_num_fields)
|
|
+ self.max_num_fields,
|
|
+ self.separator)
|
|
self.list.extend(MiniFieldStorage(key, value)
|
|
for key, value in query)
|
|
FieldStorageClass = None
|
|
@@ -649,7 +655,8 @@ class FieldStorage:
|
|
headers = rfc822.Message(self.fp)
|
|
part = klass(self.fp, headers, ib,
|
|
environ, keep_blank_values, strict_parsing,
|
|
- max_num_fields)
|
|
+ max_num_fields,
|
|
+ separator=self.separator)
|
|
|
|
if max_num_fields is not None:
|
|
max_num_fields -= 1
|
|
@@ -817,10 +824,11 @@ class FormContentDict(UserDict.UserDict)
|
|
form.dict == {key: [val, val, ...], ...}
|
|
|
|
"""
|
|
- def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
|
|
+ def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0, separator=None):
|
|
self.dict = self.data = parse(environ=environ,
|
|
keep_blank_values=keep_blank_values,
|
|
- strict_parsing=strict_parsing)
|
|
+ strict_parsing=strict_parsing,
|
|
+ separator=separator)
|
|
self.query_string = environ['QUERY_STRING']
|
|
|
|
|