2011-12-05 11 views
1

私は私たちのシステム上でコードを実行することができるシステムで作業しています。コードはサンドボックス化されていますが、コードが特定のステートメント、特にインポートを使用しているかどうかを知りたいと思っています。これは、プラットフォームのガイドラインに反する悪意のあるコードやコードを素早くチェックするために使用されます。コードは人間によって後でチェックされるため、唯一のチェックではありませんが、最悪の場合を自動的にフィルタリングすることが望ましい。特定のステートメントのためのPythonコードを確認してください

コードを実行せずに、たとえばコードがsys(または、sysの一部)をインポートしているかどうかを確認するにはどうすればよいでしょうか?正規表現を使ってコードを検索すると、より良い/良い方法が得られることを願っています。

ボーナスの質問:もっと複雑な声明はどうでしょうか?たとえば、モジュールbarからfooを呼び出しますか?

編集:これはセキュリティに関する質問ではありません。それは、コード内の特定のステートメントを見つけることです。私のコメントを参照してください。このユーザーコードはユーザーサンドボックス内でのみ実行されるため、自分のサンドボックスを破壊することができます。しかし、彼らのコードが「認定」されれば、認定される前に他のユーザのサンドボックスで実行することができます。自動化された小切手が最悪の犯罪を発見することができれば、それは役に立ちます。

+0

人間は非常に包括的なチェックを行う必要があります。たとえば、 'exec'コマンドを使ってここに実装する単純なシステムのやり方を見つけることができます。 – Oliver

+0

私は間違っているかもしれませんが、ソースファイルをテキストファイルとしてスキャンする以外の方法は考えられません。Pythonインタプリタでそれらを実行させると、インポートステートメントとモジュールの前にコードを調べることができません。レベルの関数が実行されました...しかし、おそらく私は問題の一部を見逃していますか? – mac

+0

@Oliver ...まだ...人間でさえ、コードが難読化されていると困っているかもしれません(例えばpickled/zipped/rot13'sなど) – mac

答えて

0

ast Pythonモジュールを使用してPythonコードを分析することができます。

https://stackoverflow.com/a/8255293/589206

ここにあなたのimport文の問題のためのソリューションです:ここに非常によく似た質問に対する私の答えは、参照してください

import ast 
import sys 

class FunctionNameFinder(ast.NodeVisitor): 
     def visit_Import(self, node): 
       print "Importing on line", node.lineno, ":", 
       for i in node.names: print i.name, 
       print 

with open(sys.argv[1], 'rU') as f: 
     FunctionNameFinder().visit(ast.parse("".join(f.readlines()))) 

もちろん、これは、悪意のあるユーザーがある場合に役立つことはありませんコードを難読化するために多くの努力を払っていますが、実際のサンドボックスを使用する方法があります。しかし、それは最初のところあなたの質問ではありませんでした。

+0

正直言って、これが正規表現を使うよりもどうやっていいのか分かりません...最高の桁違いで、同じ制限があります。 – mac

+0

このメソッドを使用してボーナス問題を解決することもできます。これは正規表現を使用するのが難しくなります。 – hochl

+0

上記のLiquid Fireのコードのような簡単なトリックでは機能しません。 – Voo

3

1024 ** 1024 ** 1024 

はまだあなたのインタプリタをかむだろうので、私は本当に人工サンドボックスのこの種をやろうと気にしないでしょう。

かさえ、この

eval("__vzcbeg__('gvzr').nfpgvzr()") 

あなたは信頼されていないPythonのコードを実行するためのpypyのsandboxその程度、最も安全な方法にいくつかのセキュリティの外観をしたい場合。 pysandboxのようないくつかのpythonのみのモジュールがありますが、私は個人的にpypyサンドボックスを提案しています。

それは常にトリッキーなことを行うことができますので、あなたは、単にコードの静的解析によってこれを行うことはできません
+0

OPは彼がすでに使用しているので、サンドボックスこのようなチェックは、サンドボックスを破り、禁止を強制しようとする試みを認識することを意図しているかもしれません。 – mac

1

、例えば:

>>> getattr(__builtins__, "__" + chr(105) + "mport__")("sys") 
<module 'sys' (built-in)> 

あなたが見ることができるよう、解体、コードまたはASTウォンを見ています」

>>> import dis 
>>> dis.dis(lambda: getattr(__builtins__, "__" + chr(105) + "mport__")("sys")) 
    1   0 LOAD_GLOBAL    0 (getattr) 
       3 LOAD_GLOBAL    1 (__builtins__) 
       6 LOAD_CONST    1 ('__') 
       9 LOAD_GLOBAL    2 (chr) 
      12 LOAD_CONST    2 (105) 
      15 CALL_FUNCTION   1 
      18 BINARY_ADD 
      19 LOAD_CONST    3 ('mport__') 
      22 BINARY_ADD 
      23 CALL_FUNCTION   2 
      26 LOAD_CONST    4 ('sys') 
      29 CALL_FUNCTION   1 
      32 RETURN_VALUE 
+0

私はchr(73)が間違いだったと思います。なぜなら、それは私にとってはアスキーであり、 "Import"は私のためにエラーを投げるからです。小文字iの場合は105でうまく動作します。 – Voo

+0

本当にありがとうございました。 –

1

私はこの種のものを確実に検出することはできないと思います。次のことを考えてみましょう:

>>> f = None 
>>> b = vars()[[f for f in vars() if 'ti' in f][0]] 
>>> m = getattr(b, [f for f in dir(b) if 't_' in f][0]) 
>>> m('x\x9c+\xae,\x06\x00\x02\xc1\x01`'.decode('zip')) 
<module 'sys' (built-in)> 
0

何をしようとすることは一般的なシナリオです:あなたはすでにサンドボックス内で実行することにより、コードの動的解析を行っています。あなたの上に静的な解析をしたいと思っていて、別のツールを使ってプログラムを読んでいます。

両方のアプローチにはそれぞれ独自の欠点があり、計算の性質上、それらのどれも間違った種類の潜在的なシナリオを提供することはできません。それでも2つの組み合わせは、より高い信頼レベルで多くの有用な情報を提供します。

C/C++などの一般的な言語では、コードを深く分析し、セキュリティに関連する問題を含む多くの潜在的な問題を報告する強力なツール(Lintなど)があります。

残念ながら、Pythonには堅牢性レベルが高いツールはありません。それを言って、あなたはまだたくさんのことをすることができます。 PyLintを使うのが最善の選択だと思います。

PyLintにはコード分析の標準ルールがいくつか用意されていますが、独自のコードの匂いをカスタマイズするためにPyLintをオーバーライドできます。

たとえば、使用しているモジュールの種類を確認したい場合は、imports checkerを使用できます。より複雑なシナリオを処理するために、機能をカスタマイズして拡張することができます。 documentation for enhancing PyLintをご覧ください。

tutorialを見てみましょうが始めるために:本当の砂のボクシングは確かに非常に困難である

1

ますが、それはあなたがキャッチしようとインポート文がある場合は、このことを考慮してください。

>>> org_imp = __builtins__.__import__ 
>>> def imp_hook(*args, **kw): 
    if args[0] == 'sys': 
     print 'Gotcha!!' 
     return None 
    return org_imp 

>>> __builtins__.__import__ = imp_hook 
>>> import sys 
Gotcha!! 
>>> sys 
>>> print sys 
None 

この作業は、インポート文そのものの複雑さに関係なく行われます。

注:単に&を返さないで、意味のある例外をスローしますが、あなたはそのアイデアを得るでしょう!

関連する問題