<p>Die Numpy-Ladefunktion mit bösen Daten führt zur Befehlsausführung</p>

Erstellt am 16. Jan. 2019  ·  32Kommentare  ·  Quelle: numpy/numpy

Die Numpy-Ladefunktion mit bösen Daten führt zur Befehlsausführung, wenn Angriffe böse Daten im Internet teilen.
Wenn der Benutzer es lädt, wird der Befehl ausgeführt.

Beispiel für die Wiedergabe von Code:

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')

Informationen zur Numpy / Python-Version:

1.14.6

00 - Bug 15 - Discussion Documentation good first issue

Hilfreichster Kommentar

Ich bin immer noch für eine Warnung beim Laden von Objektdaten, es kann etwas "zu spät" sein, sorgt aber für einen viel weniger verrauschten Übergang. Wir könnten beim Speichern eine Warnung hinzufügen (nur eine permanente Warnung). Es gibt offene PRs, von denen ich hoffe, dass sie sich in so etwas verwandeln. Wenn Sie Zeit damit verbringen möchten, freuen wir uns im Allgemeinen über PRs.
Es scheint mir, dass es auf jeden Fall eine Umstellung auf den Beginn eines Abschreibungszyklus ist, und ich denke, dass dies passieren wird (aber es wird früher sein, wenn jemand es aufnimmt;)). Es besteht möglicherweise eine geringe Wahrscheinlichkeit, dass eine Anfrage verzögert wird, aber ich bezweifle es, und es ist schwer zu wissen, ohne es zu versuchen.

Alle 32 Kommentare

Die Version <= 1.16.0 hat funktioniert

Ja, aus diesem Grund wurde np.load(allow_pickle=True) hinzugefügt. Jetzt könnten wir wohl versuchen, auf die Standardeinstellung False umzuschalten und eine gut lesbare Meldung "Verwenden Sie allow_pickle="True" wenn Sie möchten vertraue dieser Datei ".

Ich bin damit einverstanden, dass dies die bessere Standardeinstellung ist, daher bin ich offen dafür, diese Ablehnung voranzutreiben, auch wenn sie leider etwas laut ist, z. B. für all jene Wissenschaftler, die nur einige Daten im Labor teilen (oder sich nur selbst speichern / neu laden).

allow_pickle wurde also im April 2015 hinzugefügt, also scheint es, dass es seit numpy 1.10 hätte existieren sollen. Daher denke ich, dass dieser Schritt jetzt realistischer wird, da ich bezweifle, dass viele, die 1.17 verwenden / unterstützen, auch weiterhin 1.10 unterstützen (wodurch der Schmerz beseitigt wird, den Kwarg zu unterstützen oder nicht zu unterstützen). Obwohl es im Moment so aussieht, als ob scipy zumindest noch 1.8 in Version 1 unterstützt.

es scheint, dass es für eine lange Zeit dauern wird

Ich würde vorschlagen, eine Abwertungswarnung zu protokollieren und ein Datum anzugeben, wenn Sie einen reibungslosen Übergang wünschen.

@Plazmaz natürlich würde ich mit einer VisibleDeprecationWarning gehen, wenn wir wollen, dass Gelegenheitsbenutzer damit aufhören. Dann nach ein oder zwei Releases veraltet. Die Sache ist, dass es ärgerlich ist, herumzuarbeiten, wenn Sie müssen und das kwarg in einigen älteren Versionen nicht existiert. Denn dann müssen Sie if np.__version__ > ...: use kwarg else do not use kwarg tun, um die Warnung zu vermeiden und beide zu unterstützen.

Wie auch immer, ich denke, es besteht eine gute Chance, dass Sie es in 1.17 schaffen. Wenn Sie sich also offen für eine PR fühlen, möchten wir vielleicht die Mailingliste anpingen, um zu sehen, ob sich jemand beschwert.

Hallo, Fedora numpy RPM-Betreuer. Was ist ein guter Weg, um dies in Distributionsverpackungen zu mildern?

Ich kenne keinen schönen Weg. Abhängig von der Bedenkenstufe würde ich sehr bald eine Warnung hinzufügen, damit sie definitiv in 1.17 vorhanden ist. Wenn jemand extrem besorgt ist, könnten wir darüber diskutieren, es zurück zu portieren oder schneller voranzukommen, aber das würde sehr davon abhängen, ob Downstream davon abhängt oder nicht.

Ich arbeite daran.

cc @jeanqasaur re: Sicherheits- / Schwachstellenkompetenz

Hallo, Fedora numpy RPM-Betreuer. Was ist ein guter Weg, um dies in Distributionsverpackungen zu mildern?

@limburgher : Was macht Fedora mit genau der gleichen Funktionalität, die in Python eingebaut ist? Es ist nicht klar, dass dies etwas ist, das gemildert werden muss.

Ich bin zwar nicht dagegen, die Standardeinstellung zu ändern, aber es scheint falsch, dies als Sicherheitslücke zu deklarieren. Es funktioniert wie dokumentiert und entworfen.

Leider ist die Regel , dass , sobald eine CVE - Nummer zugeordnet ist, es spielt keine Rolle mehr , ob es ein Fehler ist oder nicht, die distros etwas versuchen zu tun , um ihre Kunden zu beweisen , dass sie Wert bieten. Ich bin mir nicht sicher, was das hier sein würde, aber Unternehmen und Mitarbeiter haben immer Probleme, die anhaltende Flut von Schwachstellen zu bewältigen, und die Tools, mit denen sie dies tun, haben nicht viel Raum für die Kommunikation von Nuancen geht. Wir haben jedoch keine Kunden, daher sollten wir dies nicht unbedingt selbst berücksichtigen.

Wir können während save und load feststellen, ob eine bestimmte Datei Pickle verwendet oder nicht, oder? In beiden Fällen ist es wahrscheinlich gut, auf allow_pickle=False zu migrieren. In einer Zwischenzeit geben wir eine Art Abwertungswarnung aus, genau in den Fällen, in denen save oder load tatsächlich benötigt werden Pickle und allow_pickle wurde nicht angegeben.

@ eric-wieser Der Unterschied zur stdlib-Gurke besteht darin, dass load / save die Verwendung von Gurke in den meisten Fällen tatsächlich vermeiden kann (z. B. einfache Arrays primitiver Typen); pickle wird nur in exotischeren Fällen wie Objektarrays oder IIRC bestimmter komplizierter dtypes verwendet. Dies ermöglicht es Leuten, die meistens den sicheren Fall verwenden, zu übersehen, dass der unsichere Fall vorliegt, wenn sie die Dokumente nicht genau genug lesen. Angesichts der Tatsache, dass wir sowohl einen "abgesicherten Modus" als auch einen "unsicheren Modus" haben, ist es besser, wenn der "abgesicherte Modus" die Standardeinstellung ist. Für stdlib pickle OTOH ist es immer 100% unsicher 100% der Zeit, so dass es keinen Grund gibt, sich über Standardeinstellungen Gedanken zu machen.

Ehrlich gesagt, wenn es sich um eine dokumentierte, absichtliche Funktionalität handelt, kann ich die BZ guten Gewissens schließen, insbesondere wenn die Standardeinstellung sicher ist. Ich weiß nicht, wie wir mit Pythons Funktionalität umgehen. Ich werde schauen.

Nach meiner Prüfung der Spezifikation glaube ich nicht, dass wir diesbezüglich etwas von Upstream ändern.

Wurde der CVE bestritten? Dies könnte das Szenario für die Betreuer klarer machen.

Der CVE erscheint weitgehend falsch. Dass numpy.load beliebigen Code ausführen kann, ist bekannt und dokumentiert und zum Laden serialisierter Python-Objekt-Arrays erforderlich. Der Benutzer kann das Laden von Objektarrays verbieten, indem er allow_pickle=False an diese Bibliotheksfunktion übergibt.

Es wäre besser gewesen, wenn standardmäßig Objektarrays nur auf ausdrückliche Anfrage geladen worden wären, aber es ist so, wie es aus historischen Gründen ist. Der Übergang wurde bereits zuvor vorgeschlagen, und in der obigen Diskussion geht es darum, wie er auf eine Weise hergestellt werden kann, die die Abwärtskompatibilität nicht unkontrolliert beeinträchtigt.

Die unachtsame Verwendung von numpy.load , ähnlich wie beim Python-Beizen, kann jedoch zu Schwachstellen in nachgeschalteten Anwendungen führen.

Dass numpy.load beliebigen Code ausführen kann, ist bekannt und dokumentiert und zum Laden serialisierter Python-Objekt-Arrays erforderlich.

Ich würde eher nur sagen, dass es dokumentiert ist. Ich benutze numpy seit ein paar Jahren und obwohl ich kein häufiger Benutzer von numpy.save / numpy.load bin, war es mir überhaupt nicht klar, dass numpy.load leidet unter der gleichen Sicherheitslücke wie pickle . Natürlich wusste ich nicht, dass numpy.load pickle unter der Haube verwenden könnte (ich verwende nur numpy-native Arrays und habe nie darüber nachgedacht, genau das Szenario, das @njsmith erwähnt hat).

Die Tatsache, dass pickle anfällig ist, ist allgemein bekannt, und in der Dokumentation befindet sich eine große rote Warnung

Warnung : Das pickle -Modul ist nicht sicher gegen fehlerhafte oder böswillig erstellte Daten. Entfernen Sie niemals Daten, die von einer nicht vertrauenswürdigen oder nicht authentifizierten Quelle stammen.

Im Vergleich dazu scheinen die Dokumente von numpy.load den gesamten Sicherheitsaspekt in der Beschreibung des Schlüsselworts allow_pickle außer Acht zu lassen :

allow_pickle: _bool, optional_
Ermöglichen das Laden von Arrays mit eingelegten Objekten, die in npy-Dateien gespeichert sind. Gründe für das Nichtzulassen von Pickles sind die Sicherheit, da beim Laden von Pickles beliebiger Code ausgeführt werden kann. Wenn Pickles nicht zulässig sind, schlägt das Laden von Objektarrays fehl. Standard: True

Ich würde es nicht hassen, wenn wir eine große rote Warnung in die Dokumentation von numpy.load könnten, zumindest bis allow_pickle=False zum Standard wird. Bis diese Änderung vorgenommen wird, sollte das Sehen von numpy.load die gleichen roten Fahnen in seinem Kopf auslösen, die pickle.load auslösen.

Dokumentation PR willkommen für numpy.load

Die Dokumentation enthält jetzt eine Warnung zu Gurke

Leider ist die Regel, dass es nach der Zuweisung einer CVE-Nummer nicht mehr wichtig ist, ob ein Fehler vorliegt oder nicht. Die Distributionen müssen versuchen, etwas zu tun, um ihren Kunden zu beweisen, dass sie einen Mehrwert bieten. Ich bin mir nicht sicher, was das hier sein würde, aber Unternehmen und Mitarbeiter haben immer Probleme, die anhaltende Flut von Schwachstellen zu bewältigen, und die Tools, mit denen sie dies tun, haben nicht viel Raum für die Kommunikation von Nuancen geht.

@njsmith es ist nicht so schlimm : wir werden numpy.load standardmäßig auf allow_pickle bis False , was eigentlich keine völlig dumme Idee ist.

Das einzige Risiko, das ich dabei sehe, ist, dass jedes Projekt, das allow_pickle nicht explizit setzt, kaputt geht.

Es ist nicht nur-End - User - Projekte müssen wir uns Sorgen um - ich mache mir Sorgen um Downstream - Bibliotheken bieten mylib.load , dass Wraps np.load . Diese können keine Objektarrays laden. Eines von drei Dingen wird mit ihnen passieren:

  • Sie bleiben verlassen und arbeiten nie mehr wie früher an Objektarrays. Benutzer werden feststellen, dass ihre Daten als Geiseln gehalten werden, und müssen numpy herunterstufen, um sie wiederherzustellen.
  • Sie veröffentlichen die Einstellung allow_pickle=True , um das alte Verhalten wieder aufzunehmen. Dies sind die nachgelagerten Bibliotheken, die darauf hinweisen, dass dies kein Angriffsvektor ist, den sie interessieren. Dies kostet sie immer noch eine inkompatible Version
  • Sie werden allow_pickle=False in ihrer eigenen API verfügbar machen und das Problem stromabwärts verschieben.

Meine Präferenz wäre:

  • Tun Sie nichts mit np.save . Ein lang anhaltender Skriptabsturz am Ende beim Speichern eines Objektarrays ist eine schreckliche Erfahrung.
  • Ändern Sie die Standardeinstellung in np.load in None . Erkennen Sie den Benutzer, der True oder False explizit übergibt, und geben Sie ein UserWarning , in dem die Gefahren erläutert werden, und bitten Sie ihn, zwischen Sicherheit ( False ) und Objekt zu wählen Array-Unterstützung ( True ). Standardmäßig wird der Status Quo nach dem Ausgeben dieser Warnung verwendet. Ich verstehe, dass das Problem hier mangelndes Bewusstsein ist. Keine der beiden Entscheidungen ist in allen Fällen richtig, daher denke ich nicht, dass wir plötzlich ohne Vorwarnung unsere Meinung über die Standardeinstellung ändern sollten.

@ Eric-Wieser guter Punkt über den Schmerz eines abstürzenden Skripts. Ich wäre bereit, standardmäßig ein UserWarning .

Die Frage ist, was wir langfristig in load tun wollen. Ich bin mir nicht sicher, ob ich es mag, alle zu zwingen, das kwarg zu verwenden (um die Warnung zum Schweigen zu bringen), wenn das Array sicher ist. Obwohl es den Vorteil hat, dass keine Gefahr besteht, jemanden aus seinen Daten auszusperren ... OTOH, wenn die Warnung nur beim "unsicheren" Laden angezeigt wird, kann es zu spät sein. Im Moment denke ich, dass ich es etwas vorziehen würde, die Übergangszeit etwas länger zu machen.

OTOH, wenn die Warnung nur bei "unsicherer" Last angezeigt wird, ist es möglicherweise zu spät.

Entweder:

  • Die Bibliothek / das Skript existiert bereits und wird veröffentlicht - alles, was wir tun, ist bereits zu spät
  • Die Bibliothek / das Skript wird noch entwickelt. Der Entwickler sollte die Warnung während lokaler Tests für sichere Dateien sehen und in der Lage sein, eine fundierte Entscheidung darüber zu treffen, welches Verhalten er möchte. Aus diesem Grund sollten wir die Warnung auch dann ausgeben, wenn das Array sicher ist (und wahrscheinlich vor dem Laden, nur für den Fall, dass das Python-Äquivalent von -Werror festgelegt ist).

Ja, ich stimme definitiv für Bibliotheken zu, aber ich denke, dass es für die große Anzahl kürzerer Skripte etwas ärgerlich sein kann.

Ändern Sie die Standardeinstellung in np.load in None . Erkennen Sie den Benutzer, der True oder False explizit übergibt, und geben Sie ein UserWarning , in dem die Gefahren erläutert werden, und bitten Sie ihn, zwischen Sicherheit ( False ) und Objekt zu wählen Array-Unterstützung ( True ). Standardmäßig wird der Status Quo nach dem Ausgeben dieser Warnung verwendet. Ich verstehe, dass das Problem hier mangelndes Bewusstsein ist. Keine der beiden Entscheidungen ist in allen Fällen richtig, daher denke ich nicht, dass wir plötzlich ohne Vorwarnung unsere Meinung über die Standardeinstellung ändern sollten.

Das klingt aber super nervig. Die meisten Leute (glaube ich) speichern / laden keine Objektarrays. Und der schlimmste Fall, wenn jemand die Warnung übersieht, ist (irgendwann), dass sein Skript beim Laden abstürzt, die Daten auf der Festplatte immer noch sicher sind und er es erneut mit dem Flag allow_pickle versucht.

Liegt es außerhalb der Verantwortung von numpy, zuerst sicher zu laden und nur dann zu schreien, wenn dies aufgrund von Objektarrays fehlschlägt? Dies würde zusätzliche Arbeit für die meisten (nicht objektiven) Anwendungsfälle beseitigen, aber ich denke, dies würde auch die Sichtbarkeit des gesamten Sicherheitsproblems verringern. Andererseits denke ich, dass "Benutzer sollten sehr bewusst gemacht werden" und "Benutzer sollten nicht belästigt werden" hier etwas widersprüchliche Bemühungen sind.

* 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.

Was ist mit diesem Patch ?

* 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.

Was ist mit diesem Patch:

--- 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")

Ich bin immer noch für eine Warnung beim Laden von Objektdaten, es kann etwas "zu spät" sein, sorgt aber für einen viel weniger verrauschten Übergang. Wir könnten beim Speichern eine Warnung hinzufügen (nur eine permanente Warnung). Es gibt offene PRs, von denen ich hoffe, dass sie sich in so etwas verwandeln. Wenn Sie Zeit damit verbringen möchten, freuen wir uns im Allgemeinen über PRs.
Es scheint mir, dass es auf jeden Fall eine Umstellung auf den Beginn eines Abschreibungszyklus ist, und ich denke, dass dies passieren wird (aber es wird früher sein, wenn jemand es aufnimmt;)). Es besteht möglicherweise eine geringe Wahrscheinlichkeit, dass eine Anfrage verzögert wird, aber ich bezweifle es, und es ist schwer zu wissen, ohne es zu versuchen.

Könnten Sie dieses Problem bitte schließen, da auf es unter https://nvd.nist.gov/vuln/detail/CVE-2019-6446 verwiesen wird, aufgrund dessen Nexus iq es immer noch als anfällig ansieht

danke @ Manjunath07

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

inducer picture inducer  ·  3Kommentare

astrofrog picture astrofrog  ·  4Kommentare

thouis picture thouis  ·  4Kommentare

qualiaa picture qualiaa  ·  3Kommentare

kevinzhai80 picture kevinzhai80  ·  4Kommentare