Должен ли я использовать eval() или call_user_func()?

StackOverflow https://stackoverflow.com/questions/662698

  •  20-08-2019
  •  | 
  •  

Вопрос

Я работаю над проектом PHP и хочу запустить код, полученный из базы данных MySQL.Шансов внедрения небезопасного кода нет, поэтому единственное, что меня беспокоит, — это производительность.Должен ли я использовать eval(), чтобы напрямую запустить код, или проанализировать его, чтобы вместо него его запускал call_user_func()?

Например, если я получил код «myfunc(1,2,3);другаяФунк(3,2,1);"
Я могу eval() напрямую запустить код.

Но для call_user_func() мне пришлось бы проанализировать строку, чтобы ее можно было запустить.Так какую функцию лучше использовать в этом случае?

Это было полезно?

Решение

Как правило, я всегда стараюсь держаться как можно дальше от eval().Однако этот случай выглядит хорошим кандидатом на эту роль.

Ты говоришь «Нет возможности внедрения небезопасного кода», поэтому большой вопрос:есть ли вероятность того, что в базе данных окажется неработающий код?

Если нет, то eval() является решением, но если есть, то более безопасным выбором может быть правильный синтаксический анализ и регистрация ошибок и т. д.(я считаю, что использование call_user_func_array() теоретически быстрее, поэтому любые накладные расходы на синтаксический анализ могут стать незначительными)

Другие советы

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

Многие люди согласны этого eval() следует всегда, без исключения, избегать в коде PHP.Всегда есть альтернатива.

Однако в этом случае я думаю, что мне придется сказать, что использование eval() будет для вас лучшим решением, поскольку вы уже храните PHP-код в БД, поэтому использование eval() не увеличит ваш риск. дальше этого.

Однако я бы порекомендовал это

  1. Вы пытаетесь проверить код перед тем, как использовать eval(), будучи консервативным в том, что вы разрешаете.Предположим, что злоумышленник каким-то образом проник в вашу базу данных, хотя это маловероятно.
  2. По крайней мере, вы серьезно задумались о том, чтобы переписать свое приложение так, чтобы код PHP не хранился в базе данных.Если вы храните сложные структуры данных, подумайте о чем-то вроде JSON или даже XML.Для них существуют безопасные парсеры.

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

Я думаю, что синтаксический анализ увеличит накладные расходы, но единственный способ убедиться в этом — запустить тесты.Попробуйте оба способа с различными функциями и посмотрите, каковы будут ваши результаты.Используйте код, который представляет то, что вы собираетесь хранить.

Удачи!

Используйте eval().Все остальное не стоит усилий – они не будут иметь никаких положительных побочных эффектов.

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

Если предполагается, что код повлияет на ваш работающий код, используйте eval().

Вам также следует обернуть код, который вы собираетесь запустить, в блок try/catch на случай возникновения ошибки (даже если вы сказали, что ее не будет, вероятность есть, и это лучшая практика).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top