読者です 読者をやめる 読者になる 読者になる

pysandboxの話

Python security CTF

Python Advent Calendar 2015の15日目担当の たけまる(@tkmru)です。
今日はSECCON 2015 九州大会で見かけたpysandboxの話をしようと思います。

pysandboxとは

Pythonで作られたsandboxのひとつで、2010年から2013年まで開発が行われていましたが、設計上の問題によりこれ以上発展させることはできないと分かり開発が停止したという歴史をもっています。
haypo/pysandbox · GitHub

設計の問題とは

pysandboxはCPythonインタプリタ名前空間を制限することで、安全にPythonコードを実行できるsandboxを作ろうと開発されていました。
しかし、CPythonにsandboxをescapeするのに使える関数が多く、sandboxを実装するのに適していないという問題に作者は気付きました。

pysandboxの作者であるVictor StinnerはThe pysandbox project is broken [LWN.net]で、以下のように述べられています。

In my opinion, the compile() vulnerabilty is the proof that it is not possible to put a sandbox in CPython. Blocking access to the open() builtin function and the file type constructor are not enough if unrelated functions can give access indirectly to the file system. Having read access on the file system is a critical vulnerability in pysandbox and modifying CPython to not print the source code line in a traceback is also not acceptable.


I now agree that putting a sandbox in CPython is the wrong design. There are too many ways to escape the untrusted namespace using the various introspection features of the Python language. To guarantee the [safety] of a security product, the code should be [carefully] audited and the code to review must be as small as possible. Using pysandbox, the "code" is the whole Python core which is a really huge code base. For example, the Python and Objects directories of Python 3.4 contain more than 126,000 lines of C code.
The security of pysandbox is the security of its weakest part. A single bug is enough to escape the whole sandbox.

「私の見解では、compile()による脆弱性がCPythonにsandboxはおくのは不可能だという証拠となる。無関係な機能が、ファイルシステムに間接的にアクセス権を与えるとすると、内蔵関数 open() とファイル・タイプ コンストラクタへのアクセスをブロックするだけでは十分でない。ファイルシステムへの読み取りアクセスは pysandboxで重大な脆弱性となり、tracebackにコードを表示しないようCPythonを修正することもまた受け入れられない。」
「私はCPythonの上にsandboxを置くのが間違った設計だというのは正しいと思う。Pythonの機能を使って名前空間をescapeする方法はとても多い。
セキュリティ製品の安全性を保証するのに、コードは注意深く監査されるべきで、そのためにコードは出来る限り小さくなければならない。
pysandboxの下のコードはものすごく大きいPythonのコアだ。例えば、Python3.4のコードは126,000行を超えるCのコードを含む。
pysandboxのセキュリティは最弱のセキュリティとなる。ひとつのバグはsandbox全体をescapeするのに十分だ。」とのことです。
compile() を使った脆弱性が発見される以前には、__builtins__.__init__、type.__bases__をつかった脆弱性が発見されていました。

また、Pythonインタプリタの外からアプローチすべきだとも述べられています。

To build a secure sandbox, the whole Python process must be put in an external sandbox. There are for example projects using Linux SECCOMP security feature to isolate the Python process.

「セキュアなsandboxを作るためには、Pythonのプロセス全体を外部のsandboxに置く必要があり、例としてLinuxのSECCOMPのPythonプロセスの扱い方が挙げられる。」とのことです。SECCOMPはlinuxカーネルの機能の1つで、どのシステムコールを実行して、どのシステムコールを実行しないかをシステムコールのフィルターとして設定できるというものです。

speakerdeck.com

このような経緯があるため、PythonのsandboxがCTFに出題されるようになったのだと思います。

おわりに

Pythonでsandboxを作るのは難しそうだという話でした。
sandboxは面白そうなので時間をつくって他のものについても調べたり作ったりしたいと思います。
アドカレ投稿遅れてすみませんでしたm(_ _)m