Blob Blame History Raw
From b272ff74ae319a82e4d3e3de1348b2a6115f6501 Mon Sep 17 00:00:00 2001
From: Paul Ivanov <pivanov5@bloomberg.net>
Date: Wed, 30 Jan 2019 14:22:44 -0800
Subject: [PATCH] BUG: load fails when using pickle without allow_pickle=True

a partial mitigation of #12759.

see also https://nvd.nist.gov/vuln/detail/CVE-2019-6446
---
 numpy/core/tests/test_regression.py |  2 +-
 numpy/lib/format.py                 |  8 ++++++--
 numpy/lib/npyio.py                  | 17 ++++++++++++-----
 numpy/lib/tests/test_format.py      | 15 +++++++++------
 numpy/lib/tests/test_io.py          |  2 +-
 5 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 52793d453..b144aec17 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -96,7 +96,7 @@ class TestRegression(object):
         ca = np.char.array(np.arange(1000, 1010), itemsize=4)
         ca.dump(f)
         f.seek(0)
-        ca = np.load(f)
+        ca = np.load(f, allow_pickle=True)
         f.close()
 
     def test_noncontiguous_fill(self):
diff --git a/numpy/lib/format.py b/numpy/lib/format.py
index 363bb2101..e6144b3a6 100644
--- a/numpy/lib/format.py
+++ b/numpy/lib/format.py
@@ -602,7 +602,7 @@ def write_array(fp, array, version=None, allow_pickle=True, pickle_kwargs=None):
                 fp.write(chunk.tobytes('C'))
 
 
-def read_array(fp, allow_pickle=True, pickle_kwargs=None):
+def read_array(fp, allow_pickle=False, pickle_kwargs=None):
     """
     Read an array from an NPY file.
 
@@ -612,7 +612,11 @@ def read_array(fp, allow_pickle=True, pickle_kwargs=None):
         If this is not a real file object, then this may take extra memory
         and time.
     allow_pickle : bool, optional
-        Whether to allow reading pickled data. Default: True
+        Whether to allow writing pickled data. Default: False
+
+        .. versionchanged:: 1.14.3
+            Made default False in response to CVE-2019-6446.
+
     pickle_kwargs : dict
         Additional keyword arguments to pass to pickle.load. These are only
         useful when loading object arrays saved on Python 2 when using
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
index 76b135cc2..ef84d68fd 100644
--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -130,7 +130,11 @@ class NpzFile(object):
         An object on which attribute can be performed as an alternative
         to getitem access on the `NpzFile` instance itself.
     allow_pickle : bool, optional
-        Allow loading pickled data. Default: True
+        Allow loading pickled data. Default: False
+
+        .. versionchanged:: 1.14.3
+            Made default False in response to CVE-2019-6446.
+
     pickle_kwargs : dict, optional
         Additional keyword arguments to pass on to pickle.load.
         These are only useful when loading object arrays saved on
@@ -166,7 +170,7 @@ class NpzFile(object):
 
     """
 
-    def __init__(self, fid, own_fid=False, allow_pickle=True,
+    def __init__(self, fid, own_fid=False, allow_pickle=False,
                  pickle_kwargs=None):
         # Import is postponed to here since zipfile depends on gzip, an
         # optional component of the so-called standard library.
@@ -265,7 +269,7 @@ class NpzFile(object):
         return self.files.__contains__(key)
 
 
-def load(file, mmap_mode=None, allow_pickle=True, fix_imports=True,
+def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
          encoding='ASCII'):
     """
     Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.
@@ -287,8 +291,11 @@ def load(file, mmap_mode=None, allow_pickle=True, fix_imports=True,
         Allow loading pickled object arrays stored in npy files. Reasons for
         disallowing pickles include security, as loading pickled data can
         execute arbitrary code. If pickles are disallowed, loading object
-        arrays will fail.
-        Default: True
+        arrays will fail. Default: False
+
+        .. versionchanged:: 1.14.3
+            Made default False in response to CVE-2019-6446.
+
     fix_imports : bool, optional
         Only useful when loading Python 2 generated pickled files on Python 3,
         which includes npy/npz files containing object arrays. If `fix_imports`
diff --git a/numpy/lib/tests/test_format.py b/numpy/lib/tests/test_format.py
index 2d2b4cea2..04e090ca7 100644
--- a/numpy/lib/tests/test_format.py
+++ b/numpy/lib/tests/test_format.py
@@ -426,7 +426,7 @@ def roundtrip(arr):
     f = BytesIO()
     format.write_array(f, arr)
     f2 = BytesIO(f.getvalue())
-    arr2 = format.read_array(f2)
+    arr2 = format.read_array(f2, allow_pickle=True)
     return arr2
 
 
@@ -553,7 +553,7 @@ def test_pickle_python2_python3():
         path = os.path.join(data_dir, fname)
 
         for encoding in ['bytes', 'latin1']:
-            data_f = np.load(path, encoding=encoding)
+            data_f = np.load(path, allow_pickle=True, encoding=encoding)
             if fname.endswith('.npz'):
                 data = data_f['x']
                 data_f.close()
@@ -575,16 +575,19 @@ def test_pickle_python2_python3():
         if sys.version_info[0] >= 3:
             if fname.startswith('py2'):
                 if fname.endswith('.npz'):
-                    data = np.load(path)
+                    data = np.load(path, allow_pickle=True)
                     assert_raises(UnicodeError, data.__getitem__, 'x')
                     data.close()
-                    data = np.load(path, fix_imports=False, encoding='latin1')
+                    data = np.load(path, allow_pickle=True, fix_imports=False,
+                                   encoding='latin1')
                     assert_raises(ImportError, data.__getitem__, 'x')
                     data.close()
                 else:
-                    assert_raises(UnicodeError, np.load, path)
+                    assert_raises(UnicodeError, np.load, path,
+                                  allow_pickle=True)
                     assert_raises(ImportError, np.load, path,
-                                  encoding='latin1', fix_imports=False)
+                                  allow_pickle=True, fix_imports=False,
+                                  encoding='latin1')
 
 
 def test_pickle_disallow():
diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py
index 2daa0153b..bde256741 100644
--- a/numpy/lib/tests/test_io.py
+++ b/numpy/lib/tests/test_io.py
@@ -87,7 +87,7 @@ class RoundtripTest(object):
 
         """
         save_kwds = kwargs.get('save_kwds', {})
-        load_kwds = kwargs.get('load_kwds', {})
+        load_kwds = kwargs.get('load_kwds', {"allow_pickle": True})
         file_on_disk = kwargs.get('file_on_disk', False)
 
         if file_on_disk:
-- 
2.21.0