2012-03-22 3 views
2

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

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

  • шаблон вводит пользователем, с тегами, такими как [[contact.name]] и тому подобное.
  • при сохранении, регулярное выражение преобразует их в переменные PHP, поэтому приведенный выше подстановочный знак становится {$contact['name']} в строке шаблона.
  • Мы также проверяем наличие чего-либо, что может быть преобразовано в доступную переменную из суперглобальной области, поэтому [[_SERVER]], [[GLOBALS]] и т. Д., А также [[this все не разрешены и зарегистрированы как попытки взлома.
  • Другие символы, имеющие особое значение в строке с двойными кавычками ($, " и \), также экранированы.
  • процесс генерации выглядит следующим образом:
    • поколение - метод класса, который запускается. Единственная переменная, которая проходит, равна $contact, которая представляет собой массив.
    • строка шаблона считывается в другую локальную переменную (в данном случае $__templateString). Пользователи могут теоретически получить доступ к этой переменной в своих шаблонах, но на самом деле это не имеет значения, если они это сделают - это не риск для безопасности, просто тупой.
    • Код для создания шаблона является то просто eval('return "' . $__templateString . '";');

Все отверстия я здесь отсутствует? Я почти уверен, что единственными потенциальными рисками являются вопросы доступа к сфере видимости, и я думаю, что я накрыл все свои базы там.

+0

Я не знаю, но такие места, как кододелат, делают это. Я часто задавался вопросом, как это сделать. –

+0

@Dagon https://github.com/Viper-7/Deployable-PHP-Codepad chrooting и заблокированные системные разрешения для пользователя, что сценарий выполняется как. Это намного сложнее, чем «eval». – deceze

+0

Если вы хотите что-то быстрое и безопасное, вы должны использовать [handelbars] (http://handlebarsjs.com/) и скомпилировать свой PHP с помощью [hiphop] (https://github.com/facebook/hiphop-php/), нам действительно не нужно другое умение. – rook

ответ

1

Так что, если я вхожу в этот шаблон:

" . mysql_query('DROP TABLE users') . " 

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

+0

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

+0

Итак, '{$ (mysql_query()}}' then. [Это верно в строках.] (Http://www.php.net/manual/en/language.types.string.php#language.types.string .parsing) Я предполагаю, что основной момент заключается в том, что попытка блокировки 'eval' - это тяжелая битва. Вы должны знать все * возможные способы выполнения кода (и их очень много) и вы должны попытаться заблокировать каждого из них с помощью регулярного выражения, которое будет иметь исключения для исключений. Вас интересует только крошечный аспект 'eval', но ему необходимо бороться с последними нежелательными побочными эффектами. разумный способ разработки. – deceze

+0

ooh, nice catch. Я не знал, что синтаксис возможен. Но на самом деле, я знаю, что это не особенно разумно * путь, но страница на синтаксическом анализе строк должна теоретически быть единственной необходимой информацией чтобы он был в безопасности (и я должен был прочитать весь путь до основания, прежде чем приходить сюда, плохой я). Я знаю, что люди всегда избегают такого рода принципа, но я плачу Мне нравится, если ты ветеран языка и достаточно уверен, чтобы попытаться, тогда почему бы и нет? Ты просто должен быть готов съесть свои слова позже, когда окажется, что ты не должен был быть таким дерзким. – pospi

1

Anecdotal drivel: Когда я был контактом безопасности для дистрибутива Linux, разработчики PHP попросили нас прекратить вызов сбоев интерпретатора при неправильных входных «уязвимостях безопасности». Они были непреклонны в том, что тот, кто поставил сценарии, был на 100% доверен, и я бы полностью ожидал, что eval() будет обрабатываться одинаково.

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

Далее, рассмотрим развертывание с mandatory access control системы, такие как AppArmor, SELinux, TOMOYO или SMACK. Таким образом вы можете restrict the potential damage from a hacked input to the minimal amount of resources necessary to do the work in the first place. (Я работаю над AppArmor с 2000 года, так что это будет мой предпочтительный выбор для многих сред. Но подумайте о других, все они представляют собой высококачественные продукты, предназначенные для решения различных проблем, и то или другое может быть лучше подходит для вашей среды .)

Смежные вопросы