3

ブリッジ先のクラスに実装することなく、データに JSON を使用してクラス インスタンスで HTTP リクエストをブリッジできるクラスを作成しています。基本的には、これがどのように機能するかです:

// This is just an ordinary class.
$service = new WeatherService();

$jhi = new JsonHttpInterface($service);
$jhi->exec();

クラスはリクエストのJsonHttpInterfaceをチェックし、PATH_INFOそのメソッドを呼び出して、クエリ文字列パラメーターを引数として適用します。

http://example.com/the_above.php/getWeather?state="CA"
$service->getWeather("CA")(最初の引数の名前が であると仮定して) に変換され$stateます。

メソッドを見つけて呼び出す方法は次のとおりです。

$method = new ReflectionMethod(get_class($this->instance), $action);
/*
... code that matches query string values to arguments of above method...
*/
$response = $method->invokeArgs($this->instance, $args);

今、私が疑問に思っているのは、そのようなシステムの脆弱性は何かということです。私はエラーチェックにかなり寛大で、存在しないメソッドやプライベート/保護されたメソッドを呼び出そうとしたときにエラーをスローするために PHP に依存しています。

  • システムをだますことは可能ですか?
  • エラーをスローする以外のことをする無効なメソッド名を渡すことは可能ですか?
  • 基本クラスまたは他のクラスのメソッドを参照することは可能ですか?

JsonHttpInterface の完全なソースは、http://blixt.org/js/two-cents.php から入手できます

4

3 に答える 3

2

初めに、

white_list を作成する必要があります。

オブジェクトの定義された関数を取得し、送信された関数名が配列に含まれているかどうかを確認します。含まれている場合は問題ありません。そうでない場合は忘れてください。

自動ホワイトリスト、または構成された手動ホワイトリストのいずれかを選択できます。

渡されたすべての値に対して変更/洗浄関数を作成する必要があります。

州の例では、州は CA またはカリフォルニア州である可能性があるため、基本的に preg_match('/\w+/') である必要があるため、データを確認するための簡単なチェックを行うことができます。

凝りたい場合は、functionName => /Regex/ のハッシュ マップである allowedValues というメソッドを作成し、関数がクラスで定義されていない場合に有効なデータ ルックアップ テーブルとして使用できるようにすることができます。 、特定の長さの文字列/数字とperhopsのみを許可する汎用のものを使用します。

    class MyClass{

    public function allowedArguments() {
        //This acts as a white list, and a cleaner/restricter
        return array(
            'myfunc' => array(
                'pattern' => '/\w+/'
                'length' => 255
            )
        );
    }

    public function myFunc($arg) {
        ... do something
    }
}
于 2010-01-14T18:52:45.723 に答える
2

ReflectionXYZ クラスを使用せずに同じことを達成できます。

call_user_func( array($this->instance, $action) , $args);

$this->instance が何であるかを制御する限り、両方とも同じ方法で保存されます。
$action は、オブジェクト/クラスのメソッド ハッシュ テーブル内のエントリを検索するために使用される文字列であり、オブジェクト コンテキストをエスケープできる (別のオブジェクトに切り替える) 魔法の記号はありません。また、SQL や SQL インジェクションなどのような解析は必要ありません。
ReflectionMethod と call_user_func_array() の両方が、メソッドの保護レベルを尊重します。例えば

class Foo {
  public function publicfn() {
    echo 'abc';
  }

  protected function protectedfn() {
    echo 'xyz';
  }
}

$obj = new Foo;
call_user_func_array(array($obj, 'publicfn'), array());
call_user_func_array(array($obj, 'protectedfn'), array());
$ro = new ReflectionMethod($obj, 'protectedfn');
$ro->invokeArgs($obj, array());

版画

abc
Warning: call_user_func_array() expects parameter 1 to be a valid callback, cannot access protected method Foo::protectedfn() in blabla on line 14

Fatal error: Uncaught exception 'ReflectionException' with message 'Trying to invoke protected method Foo::protectedfn() from scope ReflectionMethod' in blabla:16
Stack trace:
#0 blabla(16): ReflectionMethod->invokeArgs(Object(Foo), Array)
#1 {main}
  thrown in blabla on line 16

これが常に当てはまる場合は、検索することをお勧めします。たとえば、エントリがあり- MFH Fixed bug #37816 (ReflectionProperty does not throw exception when accessing protected attribute)ます。少なくとも php 5.3 ブランチには当てはまります。
$this->instance の基本クラスの public メソッドにはいつでもアクセスできます。
クラス コンテキスト内から保護されたメソッドにアクセスできます。つまり、$this と $this->instance が同じ場合、または $this->instance の派生型の保護されたメソッドにアクセスできます。例えば

class Foo {
  protected $instance;
  public function __construct(Foo $instance=null) {
    $this->instance = $instance;
  }
  public function publicfn() {
    if ( !is_null($this->instance)) {
      call_user_func_array( array($this->instance, 'protectedfn'), array());
    }
  }

  protected function protectedfn() {
    echo 'Foo::protectedfn() invoked';
  }
}

class Bar extends Foo {
  protected function protectedfn() {
    echo 'Bar::protectedfn() invoked';
  }
}

$foo = new Foo(new Bar);
$foo->publicfn();

印刷しBar::protectedfn() invokedます。しかし、それを避けるのはそれほど難しいことではありません。

于 2010-01-14T19:13:05.590 に答える
0

ユーザーが PHP コードを入力できるようにするものは、悪用される可能性が高いため、リスクが高いことは間違いありません。この方法でアクセスしたいクラスに特定のインターフェイスを実装し、実行前にインターフェイスをチェックすることを検討します。これにより、任意のクラスがそのように実行されるのを防ぎ、具体的に許可したクラスに制限するだけです。

より良い解決策は、必要なすべての呼び出しを含む静的ファイルを自動生成することです。これにより、すべての穴がどこにあるのかを推測するのではなく、特定のアクションを明示的に許可します。

于 2010-01-14T18:19:35.043 に答える