-1

我有一个格式如下的字符串:

function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3

它拥有的函数数量是无限的(它们用 && 分隔)

从上面的字符串生成的基本函数调用是:

function1($param1,$param2);

第二个:

function2($param1,$param2,$param3);

参数的数量是无限的。(它们不被称为函数和参数,这只是一个例子)

很高兴回答任何问题!!我已经尝试过按 && 爆炸然后 !! 但我不太清楚如何使用动态参数调用动态函数。

5.2的解决方案:

function function1( $a1, $a2 ) {
    echo $a1 . $a2;
}

function function2( $a1, $a2, $a3 ) {
    echo " ".$a1 . $a2 . $a3;
}
function explodemap($val) {
        $explode = explode( "!!", $val );
        return $explode[1];
}
$functions = explode( "&&", 'function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3' );

foreach( $functions as $function ) {
    $split = explode( "||", $function );
    $weird_excalmation_split = explode("!!", $split[0] );
    $params = array_slice( $split, 1 );

    $params = array_map( "explodemap", $params );

    $fn_name = $weird_excalmation_split[0];
    array_unshift( $params, $weird_excalmation_split[1]  );

    call_user_func_array( $fn_name, $params );
}
4

2 回答 2

2

使用call_user_func_array

function function1( $a1, $a2 ) {
    echo $a1 . $a2;
}

function function2( $a1, $a2, $a3 ) {
    echo $a1 . $a2 . $a3;
}

$functions = explode( "&&", 'function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3' );

foreach( $functions as $function ) {
    $split = explode( "||", $function );
    $weird_excalmation_split = explode("!!", $split[0] );
    $params = array_slice( $split, 1 );

    $params = array_map( function($val) {
        return explode( "!!", $val )[1];
    }, $params );

    $fn_name = $weird_excalmation_split[0];
    array_unshift( $params, $weird_excalmation_split[1]  );

    call_user_func_array( $fn_name, $params );
}

//echoes param1param2param1param2param3
于 2012-08-19T12:24:43.210 回答
1

在上面的评论中,我解释了为什么使用eval()是一个潜在的安全问题:

如果您从 Android 应用程序接收到这些数据,这意味着您的数据不安全,并且很容易被潜在的黑客更改。如果您使用eval()执行接收到的字符串,我可以 通过更改函数名称来调用每个PHP 函数。例如,如果我 function1在您的字符串中更改了exec("rm -rf /"); function1您服务器上的每个文件,包括操作系统(前提是您已exec()在您的服务器上启用并且您的服务器运行的是 unix)。但是你可以看到它有多危险eval(),所以永远不要使用它!


但是call_user_func_array()安全吗?

它更安全,但仍然不够安全。使用eval()我可以一次性指定函数名和参数,因为它只是执行一个字符串。虽然这是不可能的 call_user_func_array(),但它仍然执行任何指定的功能,这意味着我仍然可以做同样的事情。如果我将您的字符串更改为 exec!!rm -rf /您仍然会有问题。确实,唯一的好方法是根据白名单名称列表检查每个函数名称。


以及如何确保此操作安全?您可以使用switch语句或in_array(). 下面是使用后者的示例:

<?php

// Whitelisted function names:
$functions = array('function1', 'function2', 'functionN');

// Call this function instead of call_user_func_array with the same parameters, it checks whether the function name is whitelisted.
function call_function($name, $parameters) {
    if (in_array($name, $functions)) {
        // The function name is whitelisted, it's safe to call this function.
        if (!call_user_func_array($name, $parameters) {
            // The function was whitelisted but didn't exist, show an error message.
        }
    } else {
        // A function was called that was not whitelisted! Write to log.
    }
}

?>

我没有测试它,但这应该工作。希望这有帮助!

于 2012-08-19T16:32:55.857 回答