<p>функция загрузки numpy со злыми данными вызовет выполнение команды</p>

Созданный на 16 янв. 2019  ·  32Комментарии  ·  Источник: numpy/numpy

функция загрузки numpy со злыми данными вызовет выполнение команды, если атака разделяет вредоносные данные в Интернете,
когда пользователь загружает его, это вызовет выполнение команды.

Воспроизведение примера кода:

import numpy
from numpy import __version__
print __version__
import os
import  pickle
class Test(object):
    def __init__(self):
        self.a = 1

    def __reduce__(self):
        return (os.system,('ls',))
tmpdaa = Test()
with open("a-file.pickle",'wb') as f:
    pickle.dump(tmpdaa,f)
numpy.load('a-file.pickle')

Информация о версии Numpy / Python:

1.14.6

00 - Bug 15 - Discussion Documentation good first issue

Самый полезный комментарий

Я по-прежнему поддерживаю предупреждение при загрузке данных объекта, это может быть немного «слишком поздно», но делает переход гораздо менее шумным. Мы могли бы добавить предупреждение при сохранении (просто постоянное предупреждение). Есть открытый пиар, который, я надеюсь, трансформируется во что-то подобное. Если вы хотите потратить на это время, мы вообще рады пиарам.
Мне кажется, что в любом случае это переход к началу цикла устаревания в ближайшее время, и я думаю, что это произойдет (но это произойдет раньше, если кто-то его подберет;)). Может быть небольшая вероятность того, что запрос будет отложен, но я сомневаюсь в этом, и это трудно понять, не пытаясь.

Все 32 Комментарий

версия <= 1.16.0, работала

Да, вот почему был добавлен np.load(allow_pickle=True) , теперь я думаю, мы могли бы сделать шаг, чтобы переключиться на False и выдать хорошо читаемое сообщение "используйте allow_pickle="True" если вы доверять этому файлу ".

Я согласен с тем, что это было бы лучшим вариантом по умолчанию, поэтому я готов продвигать это осуждение, даже если это, к сожалению, немного шумно, например, для всех тех ученых, которые просто делятся некоторыми данными в лаборатории (или просто сохраняют / перезагружают себя).

Итак, allow_pickle был добавлен в апреле 2015 года, так что казалось, что он должен был существовать с момента numpy 1.10. Так что я думаю, что этот ход теперь становится более реалистичным, так как я сомневаюсь, что многие, использующие / поддерживающие 1.17, также будут поддерживать 1.10 (устраняя боль поддержки kwarg или не поддерживая его). Хотя на данный момент кажется, что по крайней мере все еще поддерживает 1.8 в версии 1.

кажется, это продлится надолго

Я бы предложил зарегистрировать предупреждение об устаревании и указать дату, если вы хотите плавный переход.

@Plazmaz, конечно, я бы пошел с VisibleDeprecationWarning, если мы хотим, чтобы обычные пользователи перестали это делать. Затем прекратите использование после одного или двух выпусков. Дело в том, что это раздражает, если нужно, и kwarg не существует в некоторых старых версиях. Потому что тогда вам нужно сделать if np.__version__ > ...: use kwarg else do not use kwarg чтобы избежать предупреждения и поддержать оба.

В любом случае, я думаю, что у вас есть шанс получить его в 1.17. Так что, если вы чувствуете, что открытый PR, но мы, возможно, захотим проверить список рассылки, чтобы узнать, не жалуется ли кто-нибудь.

Привет, сопровождающий Fedora numpy RPM. Какой хороший способ смягчить это в упаковке дистрибутива?

Я не знаю хорошего способа. В зависимости от уровня беспокойства, я бы очень скоро добавил предупреждение, так что оно определенно присутствует в 1.17. Если кто-то сильно обеспокоен, мы могли бы обсудить его бэкпорт или более быстрое перемещение, но это во многом будет зависеть от того, зависит ли от этого нисходящий поток.

Я работаю над этим.

cc @jeanqasaur re: экспертиза по безопасности / уязвимостям

Привет, сопровождающий Fedora numpy RPM. Какой хороший способ смягчить это в упаковке дистрибутива?

@limburgher : что делает Fedora с той же функциональностью, что и в Python? Неясно, нужно ли это смягчать.

Хотя я не против изменения значения по умолчанию, объявлять это уязвимостью кажется неправильным. Он работает так, как задокументировано и задумано.

К сожалению, правило состоит в том, что после присвоения номера CVE больше не имеет значения, есть ли ошибка или нет, дистрибутивы должны попытаться что- то сделать, чтобы доказать своим клиентам, что они предоставляют ценность. Не уверен, что это могло бы быть здесь, но компании и операторы всегда изо всех сил пытаются справиться с продолжающимся потоком уязвимостей, а инструменты, которые они используют для этого, не имеют большого пространства для передачи нюансов, так что давление идет. Однако у нас нет клиентов, поэтому мы не обязательно должны это учитывать.

Мы можем сказать во время save и load , использует ли конкретный файл рассол или нет, верно? Вероятно, будет хорошо перейти на allow_pickle=False в обоих случаях, с промежуточным периодом, когда мы выдаем какое-то предупреждение об устаревании именно в тех случаях, когда save или load действительно нужны использовать рассол и allow_pickle не указано.

@ eric-wieser Отличие от pickle в stdlib в том, что load / save в большинстве случаев позволяет избежать использования pickle (например, простых массивов примитивных типов); pickle используется только в более экзотических случаях, таких как массивы объектов или определенные сложные типы данных IIRC. Это позволяет людям, которые в основном используют безопасный футляр, не заметить, что небезопасный случай существует, если они недостаточно внимательно читают документацию. И в любом случае, учитывая, что у нас есть и «безопасный режим», и «небезопасный режим», лучше, чтобы «безопасный режим» был по умолчанию. Для stdlib pickle OTOH это всегда 100% небезопасно в 100% случаев, поэтому нет смысла беспокоиться о значениях по умолчанию.

Честно говоря, если это задокументированная, преднамеренная функциональность, могу с чистой совестью закрыть БЖ, особенно если по умолчанию стоит safe. Я не знаю, как мы обрабатываем функциональность Python. Я посмотрю.

Изучив спецификацию, я не думаю, что мы что-то изменим в этом отношении.

Оспаривался ли CVE? Это может сделать сценарий более понятным для сопровождающих.

CVE кажется в основном подделкой. То, что numpy.load может выполнять произвольный код, хорошо известно и документировано, и это необходимо для загрузки сериализованных массивов объектов Python. Пользователь может запретить загрузку массивов объектов, передав allow_pickle=False этой библиотечной функции.

Было бы лучше, если бы по умолчанию массивы объектов загружались только по явному запросу, но это так по историческим причинам. Этот переход предлагался и раньше, и выше обсуждалось, как сделать его таким образом, чтобы не нарушить неконтролируемым образом обратную совместимость.

Однако неосторожное использование numpy.load , как и травление Python, может привести к уязвимостям в последующих приложениях.

То, что numpy.load может выполнять произвольный код, хорошо известно и документировано, и это необходимо для загрузки сериализованных массивов объектов Python.

Скорее всего, это задокументировано. Я использую numpy в течение нескольких лет, и хотя я не частый пользователь numpy.save / numpy.load для меня вообще не было очевидно, что numpy.load страдает той же уязвимостью, что и pickle . Конечно, я не знал, что numpy.load может использовать pickle под капотом (я использую только собственные массивы numpy и никогда не задумывался об этом, это именно тот сценарий, о котором упоминал

Тот факт, что pickle уязвим, хорошо известен, и в его документации есть большое красное предупреждение вверху:

Предупреждение : модуль pickle не защищен от ошибочных или злонамеренно созданных данных. Никогда не извлекайте данные, полученные из ненадежных или неаутентифицированных источников.

Для сравнения, в документации numpy.load похоже, упоминается весь аспект безопасности в качестве отступления в описании ключевого слова allow_pickle :

allow_pickle: _bool, optional_
Разрешить загрузку массивов маринованных объектов, хранящихся в файлах npy. Причины запрета на использование солений включают безопасность, так как загрузка консервированных данных может выполнять произвольный код. Если соленья запрещены, загрузка массивов объектов завершится ошибкой. По умолчанию: True

Я бы не возненавидел, если бы мы могли поместить Большое Красное Предупреждение в документацию numpy.load , по крайней мере, пока allow_pickle=False станет значением по умолчанию. Пока это изменение не будет внесено, вид numpy.load должен вызвать в уме те же самые красные флаги, что и pickle.load .

Документация PR приветствуется для numpy.load

В документации теперь есть предупреждение о рассоле

К сожалению, правило состоит в том, что после присвоения номера CVE больше не имеет значения, есть ли ошибка или нет, дистрибутивы должны попытаться сделать что-то, чтобы доказать своим клиентам, что они предоставляют ценность. Не уверен, что это могло бы быть здесь, но компании и операторы всегда изо всех сил пытаются справиться с продолжающимся потоком уязвимостей, а инструменты, которые они используют для этого, не имеют большого пространства для передачи нюансов, так что давление идет.

@njsmith это не так уж и плохо : мы сделаем numpy.load default равным allow_pickle до False , что на самом деле не совсем глупая идея.

Единственный риск, который я вижу в этом, заключается в том, что любой проект, в котором явно не установлен allow_pickle, сломается.

Нам нужно беспокоиться не только о проектах конечных пользователей - меня беспокоят библиотеки, расположенные ниже по потоку, предоставляющие mylib.load которые обертывают np.load . Они начнут не загружать массивы объектов. С ними произойдет одно из трех:

  • Они остаются заброшенными и никогда не будут работать с массивами объектов так, как раньше. Пользователи обнаружат, что их данные находятся в заложниках, и им придется перейти на более раннюю версию numpy, чтобы восстановить их.
  • Они повторно выпускают установку allow_pickle=True чтобы возобновить старое поведение - то есть нижестоящие библиотеки, указывающие на то, что они думают, что это не тот вектор атаки, который их волнует. Это по-прежнему стоит им несовместимого выпуска
  • Они выставят allow_pickle=False в собственном API, продвигая проблему вниз по течению.

Я бы предпочел:

  • Ничего не делать с np.save . Ужасно иметь сбой длительного сценария в конце при сохранении массива объектов.
  • Измените значение по умолчанию в np.load на None . Обнаружить пользователя, который не передает True или False явно, и выдать UserWarning объяснением опасностей с предложением выбрать между безопасностью ( False ) и объектом. поддержка массивов ( True ). После появления этого предупреждения по умолчанию сохраняется статус-кво. Насколько я понимаю, проблема здесь в неосведомленности. Ни один из вариантов не является правильным во всех случаях, поэтому я не думаю, что нам следует внезапно менять свое мнение о значениях по умолчанию без предупреждения.

@ eric-wieser хороший отзыв о боли при сбое скрипта. Я бы по умолчанию дал UserWarning .

Вопрос в том, что мы хотим делать в долгосрочной перспективе в load . Я не уверен, что мне нравится заставлять всех использовать kwarg (чтобы отключить предупреждение), когда массив безопасен. Хотя его достоинства заключаются в отсутствии опасности заблокировать кого-то из их данных ... OTOH, если предупреждение появляется только при "небезопасной" загрузке, может быть слишком поздно. Сейчас я думаю, что немного предпочитаю продлить переходный период.

OTOH, если предупреждение появляется только при «небезопасной» нагрузке, может быть уже слишком поздно.

Или:

  • Библиотека / скрипт уже существует и опубликован - все, что мы делаем, уже слишком поздно
  • Библиотека / скрипт все еще в разработке. Разработчик должен видеть предупреждение во время локального тестирования безопасного файла и должен иметь возможность принять обоснованное решение о том, какое поведение он хочет. По этой причине мы должны выдать предупреждение, даже если массив безопасен (и, возможно, перед его загрузкой, на всякий случай, если у них есть Python-эквивалент -Werror set).

Да, я определенно согласен с библиотеками, но я думаю, что это может немного раздражать из-за огромного количества более коротких скриптов.

Измените значение по умолчанию в np.load на None . Обнаружить пользователя, который не передает True или False явно, и выдать UserWarning объяснением опасностей, предлагая ему выбрать между безопасностью ( False ) и объектом поддержка массива ( True ). После появления этого предупреждения по умолчанию сохраняется статус-кво. Насколько я понимаю, проблема здесь в неосведомленности. Ни один из вариантов не является правильным во всех случаях, поэтому я не думаю, что нам следует внезапно менять свое мнение о значениях по умолчанию без предупреждения.

Хотя это звучит очень раздражающе. Большинство людей (я считаю) не сохраняют / не загружают массивы объектов. И в худшем случае, если кто-то пропустит предупреждение, (в конечном итоге) его скрипт выйдет из строя при загрузке, данные по-прежнему в безопасности на диске, и они повторяют попытку с флагом allow_pickle .

Разве numpy не несет ответственности за то, чтобы сначала попытаться безопасно загрузить и кричать только в случае, если это не удается из-за массивов объектов? Это устранило бы дополнительную работу для большинства (не объектных) вариантов использования, но я думаю, что это также уменьшило бы видимость всей проблемы безопасности. С другой стороны, я думаю, что «пользователи должны быть очень осведомлены» и «пользователи не должны испытывать неудобств» - здесь несколько противоречивые усилия.

* Change the default in `np.load` to `None`. Detect the user not passing in `True` or `False` explicitly, and emit a `UserWarning` explaining the dangers, asking them to choose between security (`False`) and object array support (`True`). Default to the status quo after emitting this warning. It's my understanding that the problem here is lack of awareness. Neither choice is correct in all cases, so I don't think we should suddenly change our minds about the default without warning.

Что насчет этого патча ?

* Change the default in `np.load` to `None`. Detect the user not passing in `True` or `False` explicitly, and emit a `UserWarning` explaining the dangers, asking them to choose between security (`False`) and object array support (`True`). Default to the status quo after emitting this warning. It's my understanding that the problem here is lack of awareness. Neither choice is correct in all cases, so I don't think we should suddenly change our minds about the default without warning.

Что насчет этого патча:

--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -265,7 +265,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=None, fix_imports=True,
          encoding='ASCII'):
     """
     Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.
@@ -367,6 +367,16 @@ def load(file, mmap_mode=None, allow_pic
     memmap([4, 5, 6])

     """
+
+    if allow_pickle is None:
+        UserWarning("""
+        numpy.load() run without explicit setting allow_pickle option.
+        If you are not completely certain about security of the pickled
+        data, you are strongly encouraged to set allow_pickle to False,
+        otherwise you can set it to True.
+        """)
+        allow_pickle = False
+
     own_fid = False
     if isinstance(file, basestring):
         fid = open(file, "rb")

Я по-прежнему поддерживаю предупреждение при загрузке данных объекта, это может быть немного «слишком поздно», но делает переход гораздо менее шумным. Мы могли бы добавить предупреждение при сохранении (просто постоянное предупреждение). Есть открытый пиар, который, я надеюсь, трансформируется во что-то подобное. Если вы хотите потратить на это время, мы вообще рады пиарам.
Мне кажется, что в любом случае это переход к началу цикла устаревания в ближайшее время, и я думаю, что это произойдет (но это произойдет раньше, если кто-то его подберет;)). Может быть небольшая вероятность того, что запрос будет отложен, но я сомневаюсь в этом, и это трудно понять, не пытаясь.

Не могли бы вы закрыть эту проблему, поскольку она упоминается в https://nvd.nist.gov/vuln/detail/CVE-2019-6446, из-за чего nexus iq по-прежнему считает ее уязвимой.

спасибо @ Manjunath07

Была ли эта страница полезной?
0 / 5 - 0 рейтинги