mirror of
https://gitee.com/openharmony/third_party_python
synced 2024-11-23 07:19:45 +00:00
[安全问题]: 【漏洞】CVE-2024-0450
issue:https://gitee.com/openharmony/third_party_python/issues/I9H80L?from=project-issue
社区原始PR:30fe5d853b
Signed-off-by: xwx1135370 <xuyao44@huawei.com>
This commit is contained in:
parent
bc9c2db43a
commit
37dbbd43e1
@ -2038,6 +2038,66 @@ class OtherTests(unittest.TestCase):
|
||||
with zipfile.ZipFile(zip_file) as zf:
|
||||
self.assertRaises(RuntimeError, zf.extract, 'a.txt')
|
||||
|
||||
@requires_zlib()
|
||||
def test_full_overlap(self):
|
||||
data = (
|
||||
b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
|
||||
b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00a\xed'
|
||||
b'\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\d\x0b`P'
|
||||
b'K\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2'
|
||||
b'\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00aPK'
|
||||
b'\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
|
||||
b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bPK\x05'
|
||||
b'\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00\x00/\x00\x00'
|
||||
b'\x00\x00\x00'
|
||||
)
|
||||
with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
|
||||
self.assertEqual(zipf.namelist(), ['a', 'b'])
|
||||
zi = zipf.getinfo('a')
|
||||
self.assertEqual(zi.header_offset, 0)
|
||||
self.assertEqual(zi.compress_size, 16)
|
||||
self.assertEqual(zi.file_size, 1033)
|
||||
zi = zipf.getinfo('b')
|
||||
self.assertEqual(zi.header_offset, 0)
|
||||
self.assertEqual(zi.compress_size, 16)
|
||||
self.assertEqual(zi.file_size, 1033)
|
||||
self.assertEqual(len(zipf.read('a')), 1033)
|
||||
with self.assertRaisesRegex(zipfile.BadZipFile, 'File name.*differ'):
|
||||
zipf.read('b')
|
||||
|
||||
@requires_zlib()
|
||||
def test_quoted_overlap(self):
|
||||
data = (
|
||||
b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05Y\xfc'
|
||||
b'8\x044\x00\x00\x00(\x04\x00\x00\x01\x00\x00\x00a\x00'
|
||||
b'\x1f\x00\xe0\xffPK\x03\x04\x14\x00\x00\x00\x08\x00\xa0l'
|
||||
b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
|
||||
b'\x00\x00b\xed\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\'
|
||||
b'd\x0b`PK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0'
|
||||
b'lH\x05Y\xfc8\x044\x00\x00\x00(\x04\x00\x00\x01'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00aPK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0l'
|
||||
b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00'
|
||||
b'bPK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00'
|
||||
b'\x00S\x00\x00\x00\x00\x00'
|
||||
)
|
||||
with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
|
||||
self.assertEqual(zipf.namelist(), ['a', 'b'])
|
||||
zi = zipf.getinfo('a')
|
||||
self.assertEqual(zi.header_offset, 0)
|
||||
self.assertEqual(zi.compress_size, 52)
|
||||
self.assertEqual(zi.file_size, 1064)
|
||||
zi = zipf.getinfo('b')
|
||||
self.assertEqual(zi.header_offset, 36)
|
||||
self.assertEqual(zi.compress_size, 16)
|
||||
self.assertEqual(zi.file_size, 1033)
|
||||
with self.assertRaisesRegex(zipfile.BadZipFile, 'Overlapped entries'):
|
||||
zipf.read('a')
|
||||
self.assertEqual(len(zipf.read('b')), 1033)
|
||||
|
||||
def tearDown(self):
|
||||
unlink(TESTFN)
|
||||
unlink(TESTFN2)
|
||||
|
@ -339,6 +339,7 @@ class ZipInfo (object):
|
||||
'compress_size',
|
||||
'file_size',
|
||||
'_raw_time',
|
||||
'_end_offset',
|
||||
)
|
||||
|
||||
def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
|
||||
@ -380,6 +381,7 @@ class ZipInfo (object):
|
||||
self.external_attr = 0 # External file attributes
|
||||
self.compress_size = 0 # Size of the compressed file
|
||||
self.file_size = 0 # Size of the uncompressed file
|
||||
self._end_offset = None # Start of the next local header or central directory
|
||||
# Other attributes are set by class ZipFile:
|
||||
# header_offset Byte offset to the file header
|
||||
# CRC CRC-32 of the uncompressed file
|
||||
@ -1391,6 +1393,12 @@ class ZipFile:
|
||||
if self.debug > 2:
|
||||
print("total", total)
|
||||
|
||||
end_offset = self.start_dir
|
||||
for zinfo in sorted(self.filelist,
|
||||
key=lambda zinfo: zinfo.header_offset,
|
||||
reverse=True):
|
||||
zinfo._end_offset = end_offset
|
||||
end_offset = zinfo.header_offset
|
||||
|
||||
def namelist(self):
|
||||
"""Return a list of file names in the archive."""
|
||||
@ -1546,6 +1554,10 @@ class ZipFile:
|
||||
'File name in directory %r and header %r differ.'
|
||||
% (zinfo.orig_filename, fname))
|
||||
|
||||
if (zinfo._end_offset is not None and
|
||||
zef_file.tell() + zinfo.compress_size > zinfo._end_offset):
|
||||
raise BadZipFile(f"Overlapped entries: {zinfo.orig_filename!r} (possible zip bomb)")
|
||||
|
||||
# check for encrypted flag & handle password
|
||||
is_encrypted = zinfo.flag_bits & 0x1
|
||||
if is_encrypted:
|
||||
|
@ -0,0 +1,3 @@
|
||||
Protect :mod:`zipfile` from "quoted-overlap" zipbomb. It now raises
|
||||
BadZipFile when try to read an entry that overlaps with other entry or
|
||||
central directory.
|
Loading…
Reference in New Issue
Block a user