2

この設定を活用する方法を見つけようと頭を悩ませています。私のコンセプトはこれです:私のツイストサーバーは(経由でLineReceiver)メッセージを受信します。メッセージはbase64JSONであり、単一の辞書が含まれている必要があります。ディクショナリには"INSTRUCTION"、サーバーが処理する必要のあるクライアントアクションの種類を示すキーがあります。

プログラムのこの部分ではline、ネットワーク経由で受信されたbase64文字列です。

def Decode(line):
    return json.loads(base64.b64decode(line))

そして、解釈(ねじれたProtocolオブジェクトの内部)

def lineReceived(self, line):
    instruction = Decode(line)  #dict
    if instruction and "INSTRUCTION" in instruction:
        if instruction["INSTRUCTION"] in ("register", "join", "create", 
         "list", "passturn", "impmove", "warpmove","laserattack",
         "torpattack", "mine", "data", "status"):
            cmdstring = instruction["INSTRUCTION"] + "(self)"
            eval(cmdstring)

安全だと思う理由:

  • evalは、値としてプレーンな文字列を取得した場合にのみ実行されます。
  • JSONは複雑なオブジェクトをパックできず、Pythonの基本のみをパックできます。攻撃者は__str__私が受け取ったものにアクセスするべきではありませんよね?
  • 私はevalを使用して、読みにくくなりますが、12行をはるかにコンパクトに置き換えていif instruction["INSTRUCTION"] == "functionA": functionA(self)ます。特定のリストから関数を選択するためにevalを実行しています。

これは安全ですか?これは許容できるスタイルまたは形式と見なされますか?クライアントは信頼できないため、このコードブロックはマルチプレイヤーゲームに十分な堅牢性を備えていますか?(命令がゲームのルールに従っていることの検証は後で行われます。ここでは、サーバーを破壊的ないじくりから保護したいと思います。)

より標準的で安全な、私が試みていること(関数のリモート実行だと思います)を実行するためのより良い方法はありますか?

4

1 に答える 1

4

あなたは使用する方が良いでしょうgetattr()

if instruction and "INSTRUCTION" in instruction:
    instr_callable = getattr(self, 'do_' + instruction['INSTRUCTION'], None)
    if instr_callable is not None:
        instr_callable()

ここで、do_は命令名の前に付けられ、許可されたメソッドのみがこのメソッドを介して呼び出されるようにします。

命令関数がグローバル名前空間に存在する場合は、globals()代わりに使用し、マッピングとして使用します。

if instruction and "INSTRUCTION" in instruction:
    instr_callable = globals().get('do_' + instruction['INSTRUCTION'], None)
    if instr_callable is not None:
        instr_callable(self)

ただし、これらの呼び出し可能オブジェクトを明示的なマッピングに配置する方が適切です。

instr_callables = dict(
    register=register,
    join=join,
    ...
)

if instruction and "INSTRUCTION" in instruction:
    instr_callable = instr_callables.get(instruction['INSTRUCTION'], None)
    if instr_callable is not None:
        instr_callable(self)

eval()Python名前空間で任意のオブジェクトを検索する必要がある場合はほとんどありません。

于 2012-10-28T17:56:03.040 に答える