我应该使用eval()还是call_user_func()?

时间:2009-03-19 15:38:19

标签: php eval

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

例如,如果我获取的代码是“myfunc(1,2,3); anotherFunc(3,2,1);”

我可以直接eval()来运行代码。

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

6 个答案:

答案 0 :(得分:4)

将PHP存储在数据库中本身就是一种糟糕的设计气味;即使在这种情况下你很确定它永远不会包含不安全的代码,但最好尽量减少你必须做出的假设或防御的数量。如果您将PHP代码存储在数据库中,那么攻击者可以快速访问您的数据库的攻击变得更加严重,从而变成攻击者可以运行任意代码的攻击!我知道让你的数据库受到这样的破坏是不太可能的,但尽管如此,不要让一个不太可能的情况比你需要的更多地损害你的系统,这是一个很好的安全措施。

Many people agree在PHP代码中应该始终避免eval(),无一例外。总有另外一种选择。

但是,在这种情况下,我认为我必须说使用eval()对你来说是最好的解决方案,因为你已经在PHP中存储了PHP代码,所以使用eval()不会增加你的风险。

但是,我会建议

  1. 您尝试在eval()之前验证代码,在您允许的内容中保守。假设攻击者以某种方式进入你的数据库,甚至认为这是不可能的。
  2. 您至少需要认真考虑重写您的应用程序,以便PHP代码不会存储在数据库中。如果要存储复杂的数据结构,请考虑使用JSON甚至XML。存在安全解析器。
  3. 如果这个答案看起来有点反动,我很抱歉;我碰巧觉得这种事情非常重要。

答案 1 :(得分:2)

作为一般规则,我总是尽量远离eval()。 然而,这种情况看起来很适合它。

你说“没有机会注入不安全的代码”,所以最大的问题是:数据库中是否存在不工作代码的可能性?

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

答案 2 :(得分:1)

我认为解析会增加开销,但唯一可以确定的方法是运行测试。尝试使用各种功能,并查看结果。使用代表您希望存储的代码。

祝你好运!

答案 3 :(得分:1)

使用eval()。其他任何东西都不值得努力 - 它们不会有任何积极的副作用。

答案 4 :(得分:1)

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

如果代码被认为影响正在运行的代码,请转到eval()。

答案 5 :(得分:0)

你应该将你即将在try / catch块中运行的代码包装起来,以防出现错误(即使你说不存在,也有可能,这是最好的做法)