Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从JavaScript执行PHP伪代码的JSON块_Php_Javascript_Ajax_Json - Fatal编程技术网

从JavaScript执行PHP伪代码的JSON块

从JavaScript执行PHP伪代码的JSON块,php,javascript,ajax,json,Php,Javascript,Ajax,Json,在我正在开发的插件中,我想提供执行PHP伪代码的JSON块的功能。我意识到我需要设计一种JSON的特殊格式,允许我的后端PHP解析它并在其中执行伪代码 在将JSON块发送到服务器之前,这里有一个有问题的JSON块,因为它存在于JavaScript中: var codeBlock = { opts: [ { http: { method: "GET", header: "Acc

在我正在开发的插件中,我想提供执行PHP伪代码的JSON块的功能。我意识到我需要设计一种JSON的特殊格式,允许我的后端PHP解析它并在其中执行伪代码

在将JSON块发送到服务器之前,这里有一个有问题的JSON块,因为它存在于JavaScript中:

var codeBlock = {
    opts: 
    [
        {
            http: {
                method: "GET",
                header: "Accept-language: en\r\n" +
                        "Cookie: foo=bar\r\n"
            }
        }
    ],
    context: 
    {
        stream_context_create: ['opts']
    },
    contents: 
    {
        file_get_contents: ['http://www.YourDomain.com/', false, 'context']
    },
    html: 
    {
        htmlentities: ['contents']
    }
}
在上面的代码块中,我告诉PHP我想调用
file\u get\u contents
。为此,我需要定义一个名为
$opts
的选项数组,该数组被传递到
stream\u context\u create
。然后,从
stream\u context\u create
返回的结果将存储在名为
$contents
的变量中。然后,我们将从
file\u get\u contents
返回的结果存储到名为
$contents
的变量中。最后,我们将
file\u get\u contents
返回的数据转换为变量
$html

首先,我们需要构建一个简单的处理程序,将JSON发送到服务器

最重要的是,我们需要创建一个后端函数来解析结果并发回数据


问题是,在一个开放式的上下文中(可能会传递任何可能的PHP函数调用和代码序列),我们应该如何做呢?

下面是处理JSON“编码”PHP动态解析和执行的主要功能。本质上,我们按顺序解析JSON,识别变量名称。当我们遇到一个PHP对象时,我们知道其中存在一个PHP函数调用。我们遍历函数参数的数组,寻找字符串“指针”,然后用这些指针值替换。指针只是对JSON中先前定义的变量的引用,这些变量需要作为参数发送到函数调用。创建新的参数数组后,我们使用这些参数调用请求的函数,然后将结果返回到该函数对象变量定义中,在该定义中,它可以用作也可以不用作下一行的另一个函数调用的参数

/**
 * Iterates over an array containing PHP and handles calls to enabled functions and executes them.
 * @param {phpObj} array A JSON decoded array of representational PHP.
 * @return {*} Will return the results of the last function call passed in through phpObj.
 */
function parse_php_object( $arr, $config ) {

    // We define a pointer array that contains reference names to parameter placeholders
    // that will be replaced by real data.
    $pointers = array();

    foreach ( $arr as $k => $v ) {

        // Create variable definition with our first level array keys
        ${$k} = $v;

        // Populate our pointers index
        $pointers[$k] = $k;

        // When a value is an object we attempt to call functions defined within
        if ( is_object( ${$k} ) ) {

            // Convert our function object to an array
            $funcArr = (Array)${$k};

            // Use the first key of the function array as our function name to call
            $func_name = array_keys($funcArr);
            $func_name = $func_name[0];

            // Get the array of arguments to parse to our arguments array
            $func_args = $funcArr[$func_name];

            // Create an array to store the arguments to pass to our function call
            $args_arr = array();

            // Now we iterate over our function arguments looking for reference strings
            foreach ( $func_args as $arg ) {

                // We compare against the keys in our pointers index which was created above
                if ( array_key_exists( $arg, $pointers ) ) {

                    // This is now a reference to ${$k}, the originally defined definition, the returned
                    // result of the last sucessful function call
                    $p = ${$arg};

                    // We push our arguments onto the args_array which will be passed to our function call
                    array_push( $args_arr, $p );

                } else {

                    // We push our arguments onto the args_array which will be passed to our function call
                    array_push( $args_arr, $arg );
                }
            }


            // Based on the security mode selected, use either our blacklist or whitelist.
            switch ( $config['SEC_MODE'] ) {
                case 'blacklist' :
                    if ( function_exists( $func_name ) 
                         && !in_array( $func_name, $config['LISTS']['blacklist'] ) ) {
                        $function_allowed = true;
                    } else {
                        $function_allowed = false;
                    }
                    break;

                case 'whitelist' :
                    if ( function_exists( $func_name ) 
                         && in_array( $func_name, $config['LISTS']['whitelist'] ) ) {
                        $function_allowed = true;
                    } else {
                        $function_allowed = false;
                    }
                    break;
            }

            // Call the requested function if permitted
            if ( $function_allowed === true ) {

                // Reassign our variable the returned value of a function call so that further function calls can
                // search for the existence of pointers and then use the updated variable definitions. This logic
                // takes advantage of the procedural nature of PHP and the order of the sub-blocks in the php object. 
                ${$k} = call_user_func_array( $func_name, $args_arr );
            } else {
                return ("Function you requested $func_name has been disabled by backend configuration.");
            }
        }

        // When we're not an object we're something else like an array, string, int, etc. If we're an array we need
        // to recursively iterate over ourselves to convert any objects into arrays.
        else {  
            if ( is_array( ${$k} ) ) {
                array_walk_recursive( ${$k}, 'object_to_array' );
            }
        }

    }

    // Return the returned result from our final function call
    return ${$k};
}

/**
 * Converts PHP objects to arrays by typecasting.
 * @param {object} Object A self referencing PHP object.
 */
function object_to_array( &$object ) {
    if ( is_object( $object ) ) {
        (Array)$object;
    }
}
我相信这种方法使用了反射模式,因为命令决策是基于传递的数据类型做出的。此外,这可以用于大量基于AJAX的项目,而无需专门为函数定义处理接口


当然,在我们将结果发送回客户机之前,还有更多的代码执行一些类型检查、安全测试和JSON编码,但是上面显示的函数完成了大部分工作。

那么,这是否允许某人(比如)调用readdir或file\u get\u contents,以便他们可以在您的服务器上查找敏感数据?或者他们可以通过调用占用资源的函数来对您的服务器进行DDOS攻击?是的,这在理论上都是可能的。尽管在我的实现中,我已经提供并正在努力提供阻止对危险函数的函数调用的安全措施。用户可以自定义一个黑名单。另一种操作模式是白名单,它只允许该列表中提供的函数调用?在这种情况下,类似Haxe()的内容可能会很有趣。它是一种可以编译到多个平台的单一语言,包括PHP和JavaScript。我不知道它在PHP/JavaScript场景中的实际效果如何,但至少它不会打乱您的客户机-服务器体系结构。对于JSON格式,在JavaScript中,对象的属性是无序的,因此如果执行顺序很重要,
codeBlock
应该是一个数组。您正在向函数传递
opts
,但是如果您想传递字符串呢?实际上,您的JSON看起来有点像S表达式。:)