Как я могу исправить мою строку кода eval (): 1 проблема - PullRequest
0 голосов
/ 12 июня 2018

Я продолжаю получать

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 голосов
/ 12 июня 2018

Я увлекся и подумал о том, как улучшить его, на самом деле это может быть не ответ на ваш вопрос, а скорее пища для размышлений.Я вижу два решения, и оба типа являются инвазивными.

Конечно, оба решения работают только во всех случаях, если ваша формула использует только «переменные», как в вашем примере с ((WILL*0.8)/2.5)+(LEVEL/4).Если у вас есть более сложные формулы, вам придется адаптировать мои решения.

Обтекание eval и не вводить все входные данные в коде eval'd

Предполагая, что формулы находятся под вашим контролеми не предоставленный пользователем, вы могли бы улучшить свой eval, введя не все входные данные в свой eval'd-код, а только формулу.Таким образом, вам не нужно экранировать входные данные, нужно только убедиться, что формула синтаксически верна.

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 .Теперь вам не нужна вся платформа Symfony в вашем приложении, компонент языка выражений может использоваться сам по себе.Это может быть большим изменением, это зависит от того, как выглядит ваша существующая кодовая база.Если вы не использовали composer или пространства имен в своем проекте, это изменение может быть слишком большим.

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'],
    )
);

Как я уже сказал, это может быть огромное изменение, и вам, возможно, придется познакомиться с composer, если выне знаю уже.

0 голосов
/ 12 июня 2018

Для создаваемой строки потребуются кавычки вокруг строки str_replace '(и, возможно, другая пара 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']);
...