Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 81b7374

Browse files
committed
merge 3.2 (#16043)
2 parents e71abcc + 4e9cefa commit 81b7374

3 files changed

Lines changed: 36 additions & 3 deletions

File tree

Lib/test/test_xmlrpc.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ def test_bad_gzip_request(self):
845845
p.pow(6, 8)
846846
p("close")()
847847

848-
def test_gsip_response(self):
848+
def test_gzip_response(self):
849849
t = self.Transport()
850850
p = xmlrpclib.ServerProxy(URL, transport=t)
851851
old = self.requestHandler.encode_threshold
@@ -859,6 +859,26 @@ def test_gsip_response(self):
859859
self.requestHandler.encode_threshold = old
860860
self.assertTrue(a>b)
861861

862+
863+
class GzipUtilTestCase(unittest.TestCase):
864+
865+
def test_gzip_decode_limit(self):
866+
max_gzip_decode = 20 * 1024 * 1024
867+
data = b'\0' * max_gzip_decode
868+
encoded = xmlrpclib.gzip_encode(data)
869+
decoded = xmlrpclib.gzip_decode(encoded)
870+
self.assertEqual(len(decoded), max_gzip_decode)
871+
872+
data = b'\0' * (max_gzip_decode + 1)
873+
encoded = xmlrpclib.gzip_encode(data)
874+
875+
with self.assertRaisesRegexp(ValueError,
876+
"max gzipped payload length exceeded"):
877+
xmlrpclib.gzip_decode(encoded)
878+
879+
xmlrpclib.gzip_decode(encoded, max_decode=-1)
880+
881+
862882
#Test special attributes of the ServerProxy object
863883
class ServerProxyTestCase(unittest.TestCase):
864884
def setUp(self):
@@ -1093,6 +1113,7 @@ def test_main():
10931113
try:
10941114
import gzip
10951115
xmlrpc_tests.append(GzipServerTestCase)
1116+
xmlrpc_tests.append(GzipUtilTestCase)
10961117
except ImportError:
10971118
pass #gzip not supported in this build
10981119
xmlrpc_tests.append(MultiPathServerTestCase)

Lib/xmlrpc/client.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
# 2003-07-12 gp Correct marshalling of Faults
5050
# 2003-10-31 mvl Add multicall support
5151
# 2004-08-20 mvl Bump minimum supported Python version to 2.1
52+
# 2014-12-02 ch/doko Add workaround for gzip bomb vulnerability
5253
#
5354
# Copyright (c) 1999-2002 by Secret Labs AB.
5455
# Copyright (c) 1999-2002 by Fredrik Lundh.
@@ -1031,10 +1032,13 @@ def gzip_encode(data):
10311032
# in the HTTP header, as described in RFC 1952
10321033
#
10331034
# @param data The encoded data
1035+
# @keyparam max_decode Maximum bytes to decode (20MB default), use negative
1036+
# values for unlimited decoding
10341037
# @return the unencoded data
10351038
# @raises ValueError if data is not correctly coded.
1039+
# @raises ValueError if max gzipped payload length exceeded
10361040

1037-
def gzip_decode(data):
1041+
def gzip_decode(data, max_decode=20971520):
10381042
"""gzip encoded data -> unencoded data
10391043
10401044
Decode data using the gzip content encoding as described in RFC 1952
@@ -1044,11 +1048,16 @@ def gzip_decode(data):
10441048
f = BytesIO(data)
10451049
gzf = gzip.GzipFile(mode="rb", fileobj=f)
10461050
try:
1047-
decoded = gzf.read()
1051+
if max_decode < 0: # no limit
1052+
decoded = gzf.read()
1053+
else:
1054+
decoded = gzf.read(max_decode + 1)
10481055
except IOError:
10491056
raise ValueError("invalid data")
10501057
f.close()
10511058
gzf.close()
1059+
if max_decode >= 0 and len(decoded) > max_decode:
1060+
raise ValueError("max gzipped payload length exceeded")
10521061
return decoded
10531062

10541063
##

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ Core and Builtins
2626
Library
2727
-------
2828

29+
- Issue #16043: Add a default limit for the amount of data xmlrpclib.gzip_decode
30+
will return. This resolves CVE-2013-1753.
31+
2932
- Issue #22517: When a io.BufferedRWPair object is deallocated, clear its
3033
weakrefs.
3134

0 commit comments

Comments
 (0)