Что мне следует использовать - eval () или call_user_func ()?

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

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

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


person Drahcir    schedule 19.03.2009    source источник
comment
Извините за редактирование, но у меня возникает такая идея всякий раз, когда я вижу, что НЕТ ШАНСА чего-то :) Не стесняйтесь удалить это, если вы чувствуете, что этого не должно быть.   -  person Milan Babuškov    schedule 19.03.2009
comment
Извините, но это не смешно и не поучительно. Просто злоупотребление привилегиями [ИМХО].   -  person soulmerge    schedule 19.03.2009
comment
Нет никаких шансов, поскольку я единственный, у кого есть доступ на запись к базе данных, из которой он вызывает.   -  person Drahcir    schedule 19.03.2009


Ответы (6)


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

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

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

person J.C. Inacio    schedule 19.03.2009

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

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

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

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

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

Прошу прощения, если этот ответ кажется немного реакционным; Просто я чувствую, что такие вещи очень важны.

person thomasrutter    schedule 20.03.2009

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

Удачи!

person Todd R    schedule 19.03.2009

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

person soulmerge    schedule 19.03.2009

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

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

person Bob Fanger    schedule 19.03.2009

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

person alex    schedule 20.03.2009