6

クラスとメソッドの 2 つの GET 変数を取り、それらを設計したメソッドにマップする AJAX スクリプトを作成しようとしています (CodeIgniter が ajax に対してどのように機能するかに似ていると確信しています)。実行するクラスとメソッドを決定するためにユーザー入力に依存しているため、ハッカーがその手法を有利に利用する方法があるのではないかと心配しています。

コード:

//Grab and clean (just in case, why not) the class and method variables from GET
$class = urlencode(trim($_GET['c']));
$method = urlencode(trim($_GET['m']));

//Ensure the passed function is callable
if(method_exists($class, $method)){
    $class::$method();
}

この手法を使用する際に知っておくべき欠点やセキュリティ上の注意点はありますか?

4

5 に答える 5

14

ユーザーによるメソッドの呼び出しが許可されているかどうかを確認します。

// methods that user can call:
$user_methods = array("method1", "method2", "method3", );

//Ensure the passed function is callable
if(method_exists($class, $method) and in_array($method, $user_methods){
    $class::$method();
}

そうしないと、ユーザーができることを制御できなくなります。

于 2012-07-10T13:32:22.897 に答える
6
<?php
class AjaxCallableFunction
{
    public static $callable_from_ajax = TRUE;
}

$class = $_POST['class'];
$method = $_POST['method'];

if ( class_exists( $class ) && isset( $class::$callable_from_ajax ) && $class::$callable_from_ajax ) {
    call_user_func( $class, $method );
}

最良の結果を得るには、他のいくつかの回答と組み合わせてください。PHP 5.3.0 以降が必要です。インターフェイスを実装することもできます

<?php
interface AjaxCallable {}

class MyClass implements AjaxCallable 
{
    // Your code here
}

$class = $_POST['class'];
$method = $_POST['method'];

if ( class_exists( $class ) && in_array( 'AjaxCallable', class_implements( $class ) ) ) {
    call_user_func( $class, $method );
}

このアプローチは OOP の原則に従っており、非常に冗長 (保守が容易) であり、呼び出せるクラスと呼び出せないクラスの配列を維持する必要はありません。

于 2012-07-10T19:29:38.683 に答える
4

引数を渡していないことを考えると、これは今のところ比較的安全です。しかし、私はあなたのIFに次のような有効なクラスのリストを追加します:

//Ensure the passed function is callable
if(method_exists($class, $method)){
    if(in_array($class, array('controller1', 'controller2'))){
        $class::$method();
    }
}

このように、ハッカーはこの方法でフレームワーク内の可能なクラスを実際に呼び出すことはできませんが、許可したクラスのみを呼び出すことができます。

于 2012-07-10T13:30:24.317 に答える
2

この場合、 Reflectionで処理する必要があります。

必要なものの例を次に示します。

<?php
class Apple {
    public function firstMethod() { }
    final protected function secondMethod() { }
    private static function thirdMethod() { }
}

$class = new ReflectionClass('Apple');
$methods = $class->getMethods();
var_dump($methods);
?>

メソッドの実行は、 ReflectionMethods:invokeを使用して次のようになります。

  <?php
class HelloWorld {

    public function sayHelloTo($name) {
        return 'Hello ' . $name;
    }

}

$reflectionMethod = new ReflectionMethod('HelloWorld', 'sayHelloTo');
echo $reflectionMethod->invoke(new HelloWorld(), 'Mike');
?>

最後に、次のことができます。

 $class = urlencode(trim($_GET['c']));
  $method = urlencode(trim($_GET['m']));

  $allowed_methods = array("insert", "update", "delete");

  if(method_exists($class, $method) and in_array($method, $allowed_methods){
    $reflectionMethod = new ReflectionMethod($class, $method);
    $reflectionMethod->invoke(new $class, 'First Argument');
   }
于 2012-07-10T13:50:03.083 に答える
1

urlencode() は私を少し心配させます。安全かもしれませんが、もっと厳密に消毒します。文字、数字、アンダースコアのみを許可します。クラス名やメソッド名に他の文字を使用する必要はありません。見たことはないと思います。

私はこれをすべてのプロジェクトで多くのものに使用しています:

function very_safe_string( $string )
{
    return preg_replace("/[^A-Za-z0-9_]/" , '' , $string);
}

そして、他のポスターが言及しているように、明示的に許可するホワイトリストのタイプが必ずあるはずです(少なくともクラスについては、すべてのクラスにajaxからアクセスする必要があるとは限らないため)。class_exists() と method_exists() をチェックするだけでなく、

また、これらのチェックのいずれかが失敗した場合に備えて、何らかの種類の電子メール警告システムを設置することをお勧めします. 誰かが j00 を hax0r しようとしているかどうか知りたいと思います。

于 2012-07-13T09:52:17.930 に答える