如何修复我的eval()&#39代码行:1个问题

时间:2018-06-12 18:08:41

标签: php mysqli xampp eval text-based

我一直在

file: C:\xampp\htdocs\doit.php(45) : eval()'d code line: 1

我搜索过该网站但无法找到适用于我的修复程序,这是我正在使用的代码问题

     $ec = "\$sucrate=" . str_replace(array("LEVEL", "EXP", "WILL", "IQ"), array($player['level'], $player['exp'], $player['will'], $player['IQ']), $r['crimePERCFORM']) . ";";
 eval($ec);

2 个答案:

答案 0 :(得分:0)

您正在构建的字符串需要在str_replace' d字符串周围引用(以及可能还有另一个string_replace对以防止引用问题)。

示例:

$ec = "\$sucrate='" . str_replace(array("LEVEL", "EXP", "WILL", "IQ"), array($player['level'], $player['exp'], $player['will'], $player['IQ']), $r['crimePERCFORM']) . "';";

但是,虽然这应该可以解决您的问题,但使用eval的情况几乎没有问题。它肯定会让你的代码容易受到某种远程执行攻击,无论什么"保护"你放置的地方允许任何人在你的服务器上运行任何代码,就像它是你写的一样。

这样做会完全相同,只是将$sucrate变量设置为替换值。

$sucrate = str_replace(array("LEVEL", "EXP", "WILL", "IQ"), array($player['level'], $player['exp'], $player['will'], $player['IQ']), $r['crimePERCFORM']);

答案 1 :(得分:0)

我被带走了,并考虑过如何改进它,这可能实际上不是你问题的答案,而是更多的思考。我看到两种解决方案,两者都是侵入性的。

当然,如果您的公式仅使用"变量"两种解决方案仅适用于所有情况。就像在((WILL*0.8)/2.5)+(LEVEL/4)的示例中一样。如果您有更复杂的公式,您可以调整我的解决方案。

包装eval并且不会在eval&#d;代码中注入所有输入

假设公式在您的控制之下而不是用户提供的,您可以通过不在您的eval代码中注入所有输入而仅注入公式来改善您的eval。这样你就不必逃避输入,你只需要确保公式在语法上是正确的。

function calculateFormula($_vars, $_values, $_formula) {
    // This transforms your formula into PHP code which looks
    // like this: (($WILL*0.8)/2.5)+($LEVEL/4)
    $_cleanFormula = str_replace(
        $_vars,
        array_map(function($v) { return '$' . $v; }, $_vars),
        $_formula
    );

    // create the $WILL, $LEVEL, $IQ and $EXP variables in the local scope
    extract(array_combine($_vars, $_values));

    // execute the PHP-formula
    return eval('return ' . $_cleanFormula . ';');
}

// Use it like this, instead of eval
$sucrate = calculateFormula(
    array("LEVEL", "EXP", "WILL", "IQ"), 
    array($player['level'], $player['exp'], $player['will'], $player['IQ']),
    $r['crimePERCFORM']);

这仍然使用eval,因此安全方面这将是最糟糕的解决方案。但这将是你现在最接近的。

使用Symfony的表达语言

更安全的选择是使用symfony's expression language component之类的东西。现在你不需要在你的应用程序中使用整个symfony框架,表达式语言组件可以在它自己的上面使用。这可能是一个很大的变化,这取决于您现有的代码库的外观。如果您未在项目中使用过编写器或命名空间,则此更改可能太大。

require_once __DIR__ . '/vendor/autoload.php';

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

$expressionLanguage = new ExpressionLanguage();

$sucrate = $expressionLanguage->evaluate(
    $r['crimePERCFORM'],
    array(
        "LEVEL" => $player['level'],
        "EXP" => $player['exp'],
        "WILL" => $player['will'],
        "IQ" => $player['IQ'],
    )
);

正如我所说,这可能是一个巨大的变化,你可能必须熟悉作曲家,如果你不知道它。