PHP eval() 的这种使用是否可以利用?

信息安全 Web应用程序 php
2021-08-23 10:04:00

在代码审查期间,我发现了类似的内容:

function foo() {

        $a = "a";
        $expression = '$_GET["$a"]';

        return eval('return ('.$expression.');');
}

$a = foo();
echo $a;

别介意废话,这个例子被简化了,由于糟糕的设计决策,客户“真的”需要“return eval”指令。

我的猜测是否定的,因为$expressionis not $_GET["$a"],而是一个表示变量名称的字符串,所以 to 的参数eval()相当于一个“返回字符串”。

但根据 PHP 手册:

当通过引用返回时,你不应该在你的返回变量周围使用括号,因为这不起作用。您只能通过引用返回变量,而不是语句的结果。如果你使用return ($a);then 你不是返回一个变量,而是表达式的结果($a)(当然是 的值$a)。

有没有办法可以利用它?

1个回答

因为你只是回显一个 GET 变量,这很容易受到 XSS 的攻击。但这与您的使用无关eval,我认为这是问题的主要焦点。让我们来看看。

如果你用 替换eval(...)echo ...你会注意到无论你传入什么,输出都是这样的:

return ($_GET["$a"]);

这是因为您使用'and not ",所以$expression最终不会包含 GET 变量的值。因此,在您正在评估的表达式中,用户没有任何控制 - 它基本上只是一个常数。这并不危险(鉴于常量本身不包含危险代码),但也不是完全有用。你还不如把eval.

但是……如果我负责这段代码,我会很紧张。它确实看起来很不稳定,而且eval不管为什么使用都是一个巨大的危险信号。另外,谁知道我在这个答案中可能错过了什么。