8

Pythonのドキュメントにpickleは、安全ではなく、信頼できないユーザー入力を解析してはならないことが記載されています。あなたがこれを研究するならば; ほとんどすべての例は、system()を介した呼び出しでこれを示していますos.system

私にはわかりませんが、モジュールをインポートos.systemせずに正しく解釈される方法です。os

>>> import pickle
>>> pickle.loads("cos\nsystem\n(S'ls /'\ntR.") # This clearly works.
bin  boot  cgroup  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  selinux  srv  sys  tmp  usr  var
0
>>> dir() # no os module
['__builtins__', '__doc__', '__name__', '__package__', 'pickle']
>>> os.system('ls /')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> 

誰かが説明できますか?

4

4 に答える 4

9

モジュールの名前 ( os) はオペコードの一部でありpickle、モジュールを自動的にインポートします。

# pickle.py
def find_class(self, module, name):
    # Subclasses may override this
    __import__(module)
    mod = sys.modules[module]
    klass = getattr(mod, name)
    return klass

行に注意してください__import__(module)

GLOBAL 'os system'pickle バイトコード命令が実行されると、関数が呼び出されます。

このメカニズムは、モジュールが呼び出し元の名前空間に明示的にインポートされていないクラスのインスタンスを unpickle できるようにするために必要です。

于 2012-04-24T16:45:00.250 に答える
9

標準の os.system() の例よりもはるかに進んだ悪意のある Pickles の作成に関する情報が多すぎる場合は、このプレゼンテーションとそれに付随する論文を参照してください。

于 2012-04-25T00:44:28.813 に答える
6

pickletools.dis を使用して pickle を逆アセンブルすると、これがどのように機能しているかがわかります。

import pickletools
print pickletools.dis("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 は、オブジェクトの再構築に使用される命令を記録する単純なスタックベースの仮想マシンを使用します。言い換えれば、あなたの例のピクルス化された指示は次のとおりです。

self.find_class(module_name, class_name) をプッシュします。つまり、os.system をプッシュします。文字列 'ls ~' をプッシュします。最上位のスタック項目からタプルを構築します。両方ともスタック上の argtuple に callable を適用します。すなわち os.system(*('ls ~',))

ソース

于 2012-04-24T16:47:03.747 に答える
2

モジュールをインポートすると、ローカルの名前空間にのみ追加されますが、これは必ずしも現在の名前空間であるとは限りません。そうでない場合を除きます。

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> __import__('os')
<module 'os' from '/usr/lib64/python2.7/os.pyc'>
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
于 2012-04-24T16:45:44.457 に答える