5

我正在开发一个 php 项目,我想运行从 MySQL 数据库中获取的代码。没有机会注入不安全的代码,所以我唯一担心的是性能。我应该使用 eval() 以便我可以直接运行代码,还是解析它以便 call_user_func() 运行它?

例如,如果我获取的代码是“myfunc(1,2,3); anotherFunc(3,2,1);”
我可以直接 eval() 来运行代码。

但是对于 call_user_func(),我必须解析字符串才能运行它。那么在这种情况下使用哪个更好的功能?

4

6 回答 6

4

将 PHP 存储在数据库中本身就是一种不好的设计气味。即使在这种情况下,您很确定它永远不会包含不安全的代码,但尽量减少您必须做出的假设或防御的数量总是好的。如果您将 PHP 代码存储在数据库中,那么攻击者可以快速访问您的数据库的攻击会变得更加严重,变成攻击者可以运行任意代码的攻击!我知道让您的数据库像这样被破坏是极不可能的,但是即使是不太可能的情况也不要让您的系统受到超出其需要的损害,这是一种良好的安全实践。

许多人同意在 PHP 代码中应该始终避免使用 eval(),无一例外。总有替代方案。

然而,在这种情况下,我认为我不得不说使用 eval() 对你来说是最好的解决方案,因为你已经在数据库中存储了 PHP 代码,所以使用 eval() 不会增加你的风险除此之外。

但是,我建议

  1. 您尝试在 eval() 之前验证代码,在您允许的范围内保持保守。假设攻击者以某种方式进入了您的数据库,甚至认为这不太可能。
  2. 您至少认真考虑重写您的应用程序,以便 PHP 代码不存储在数据库中。如果您要存储复杂的数据结构,请考虑使用 JSON 甚至 XML 之类的东西。这些存在安全的解析器。

如果这个答案看起来有点反动,我很抱歉;我只是碰巧觉得这种事情很重要。

于 2009-03-20T01:31:11.960 回答
2

作为一般规则,我总是尽量远离 eval() 。然而,这个案例看起来是一个很好的候选者。

您说“不可能注入不安全的代码”,所以最大的问题是:数据库中是否有可能出现不工作的代码?

如果没有, eval() 是解决方案,但如果有正确的解析和错误记录/等可能是一个更安全的选择。(我相信理论上使用 call_user_func_array() 更快,所以任何解析开销都可以忽略不计)

于 2009-03-19T18:22:45.780 回答
1

我认为解析会增加开销,但您可以确定的唯一方法是对其进行测试。用各种功能尝试两种方式,看看你的结果是什么。使用代表您希望存储的内容的代码。

祝你好运!

于 2009-03-19T15:45:16.157 回答
1

使用 eval()。其他任何事情都不值得付出努力——它们不会产生任何积极的副作用。

于 2009-03-19T15:54:48.817 回答
1

您可能想看看runkit扩展,它可以在沙箱中执行 php 而不会影响正在运行的代码。

如果假设代码会影响您正在运行的代码,请使用 eval()。

于 2009-03-19T18:18:28.410 回答
0

您也应该将要运行的代码包装在 try/catch 块中,以防出现错误(即使您说不会出现错误,但仍有可能,这是最佳实践)

于 2009-03-20T01:42:31.917 回答