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

发布于 2024-07-15 03:35:03 字数 277 浏览 7 评论 0 原文

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

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

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

I'm working on a php project, and I want to run code that's fetched from a MySQL database. There's no chance of unsafe code being injected, so the only thing I'm worried about is performace. Should I use eval() so I can directly run the code, or parse it so that call_user_func() runs it instead?

For example, if the code I fetched was "myfunc(1,2,3); anotherFunc(3,2,1);"
I can eval() it directly to run the code.

But for call_user_func(), I'd have to parse the string so that it can be ran. So which is the better function to use in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦过后 2024-07-22 03:35:03

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

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

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

但是,我建议

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

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

Storing PHP in the database is a bad design smell in itself; even though in this case you are pretty sure it can never contain unsafe code, it is always good to minimize the number of assumptions or defenses like that you have to make. If you store PHP code in the database, then an attack in which an attacker gains access to your database quickly becomes a lot more serious, turning into an attack in which an attacker can run arbitrary code! I know that having your database compromised like this is highly unlikely, but nonetheless it is good security practice not to let even an unlikely situation compromise your system more than it needs to.

Many people agree that eval() should always, without exception, be avoided in PHP code. There's always an alternative.

In this case, however, I think that I would have to say that using eval() would be the best solution for you, because you are already storing PHP code in the DB, so using eval() is not going to increase your risk any further than that.

I would, however, recommend that

  1. You try to validate the code before you eval() it, by being conservative in what you allow. Assume that somehow an attacker got into your database even thought that is unlikely.
  2. You at least give some serious thought to rewriting your application so that PHP code is not stored in a database. If you are storing complex data structures, think about something like JSON or even XML instead. Safe parsers exist for these.

I'm sorry if this answer seems a bit reactionary; I just happen to feel this sort of thing is very important.

木槿暧夏七纪年 2024-07-22 03:35:03

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

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

如果没有, eval() 是解决方案,但如果有适当的解析和错误日志记录等可能是更安全的选择。 (我相信使用 call_user_func_array() 理论上速度更快,因此任何解析开销可能都可以忽略不计)

As a general rule, i always try to stay as far away from eval() as possible.
This case, however, looks like a good candidate for it.

You say "There's no chance of unsafe code being injected", so the big question is: is there a chance of unworking code being in the database?

If not, eval() is the solution, but if there is then proper parsing and error logging/etc might be a safer bet. (i believe using call_user_func_array() is faster in theory, so any parsing overhead might become negligible)

愿与i 2024-07-22 03:35:03

我认为解析会增加开销,但唯一可以确定的方法是运行测试。 使用不同的函数尝试两种方法,看看结果如何。 使用代表您希望存储的内容的代码。

祝你好运!

I would think that parsing would add overhead, but the only way you can be sure is to run tests it. Try it both ways with various functions and see what your results are. Use code that represents what you expect to store.

Good luck!

余厌 2024-07-22 03:35:03

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

Use eval(). Anything else is not worth the effort - they wouldn't have any positive side effects.

中性美 2024-07-22 03:35:03

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

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

You might want to take a look at the runkit extention, which can execute php in a sandbox not effecting the running code.

If the code is suppose to effect your running code, go for eval().

帝王念 2024-07-22 03:35:03

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

You should wrap the code you're about to run in a try/catch block too, in case there is an error (even though you said there won't be, there is a possibility, and it is best practice)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文