Использование eval() для повышения безопасности

Я признаю, что название - в основном уловка 22, но оно полностью уместно, поэтому, пожалуйста, потерпите меня немного...

Фон

Как некоторые могут знать, я работаю над PHP-фреймворком, основной целью которого является объединение функциональности между различными CMS / системами. С точки зрения разработчика, существует обширный механизм обработки ошибок и ведения журнала. Прямо сейчас есть две настройки, DEBUG_MODE а также DEBUG_VERBOSE, которые управляют выходом отладки.

Режим описывает средний и подробный контроль количества деталей. Короче говоря, есть режим, называемый "консоль", который в основном выводит отладочную информацию в консоль javascript (которая теперь доступна в главном веб-браузере рядом с вами).

Проблема

Эта [система отладки] прекрасно работает для серверов разработки, но вы абсолютно не можете использовать ее на производственном сервере, поскольку подробности отладки (включая учетные данные БД и т. Д.) Публикуются публично. И, честно говоря, кто когда-либо мигрировал из Dev. продукту сервер без нареканий каждый раз?

Решения

Поэтому я пытался найти способ исправить это. Среди моих предложенных решений:

  • Наличие параметра, который указывает платформе включить ведение журнала, только если запрос поступает с определенного IP-адреса. Проблемы безопасности для этого довольно очевидны (IP-спуфинг среди прочих).
  • Наличие параметра, содержащего выражение PHP (код), которое получает eval'd, и его возвращение используется как да / нет. Самое приятное, что установленный фреймворк может предлагать специфичные для CMS выражения, например:
    • Wordpress: current_user_can('manage_options')
    • Joomla: $user=&JFactory::getUser() && ($user->usertype=='Super Administrator') || ($user->usertype=='Administrator')
    • Таможня: $_SERVER['REMOTE_ADDR']=='123.124.125.126'
  • Это одни из двух, я хочу услышать больше предложений.

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

осветление

if(DEBUG_MODE!='none')echo 'Debug'; // this is how it is now
if(DEBUG_MODE!='none' && $USER_CONDITION)echo 'Debug'; // this is how it should be

$USER_CONDITON позволяет такие вещи, как бег is_admin() чтобы все администраторы могли видеть отладочную информацию, или, getUser()->id==45 чтобы включить его для конкретного пользователя. Или по IP, или как угодно.

4 ответа

Решение

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

Что касается осуществимости вашего подхода, то здесь нет никаких дискуссий. Вам нужна переменная логика аутентификации и вы не можете привязать ее к одной конкретной среде / среде выполнения cms.

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

И, наконец, избегайте таких заголовков вопросов на SO. ;} Или, по крайней мере, говорить о create_function Пожалуйста.

Подделка IP-адреса, достаточная для получения ответа, вряд ли произойдет. Если пользователю удается установить соединение с вашим сервером, подделывая внутренний или привилегированный IP-адрес разработчика, он контролирует ваш маршрутизатор, так что вам есть о чем беспокоиться.

Вместо запуска eval вы не можете просто написать анонимную функцию / замыкание: http://php.net/manual/en/functions.anonymous.php(поместив его в файл конфигурации, а не на веб-экран, написание сложного кода PHP в веб-форме кажется неоптимальным в любом случае)

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

Даже аргумент о том, что администратор может установить плагины в любом случае, не полностью поддерживается, потому что возможны атаки XSRF, которые могут помещать вредоносные объекты в текстовое поле (один запрос), но не могут инициировать установку плагина.

Так что нет, я бы этого не делал; Вместо этого я реализовал бы каждый мост CMS в качестве адаптера и позволил бы пользователю выбрать адаптер (и при необходимости ввести некоторые настраиваемые, очищаемые параметры) из предварительно определенного списка. (Нечто подобное было также предложено @Wrikken в комментариях)

Это ваш вызов. Скорее всего, у вас никогда не будет проблем с этим eval() путь. И можно утверждать, что большинство CMS, с которыми вы будете соединяться (Wordpress, Joomla), в любом случае разрешают произвольное выполнение кода PHP в серверной части. Но это не хороший дизайн.

Наличие параметра, содержащего выражение PHP (код), которое получает eval'd, и его возвращение используется как да / нет. Самое приятное, что установленный фреймворк может предлагать специфичные для CMS выражения, например:

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

Другие вопросы по тегам