Позвольте мне предисловие к этому, сказав, что я хорошо знаю, что выполняемый код пользователя в серверной среде является рискованным. Юмор меня - мой вопрос специфичен для оценки строк и подмножества языка, который может быть выполнен в этом контексте.Безопасность PHP: риски при оценке строки, введенной пользователем
Итак, сейчас я строю систему генерации шаблонов, и я хочу, чтобы она была быстрой. Супер, супер, супер быстро. Эта вещь собирается получить tharshhed для массовых почтовых рассылок и тому подобное. Подход, который я использую, заключается в том, чтобы пользователи могли вводить введенные пользователем теги шаблонов, которые перед сохранением превращаются в замену переменных PHP с помощью регулярных выражений. Предполагая, что мои регулярные выражения являются пуленепробиваемыми, чувствуете ли вы, что безопасность этого процесса приемлема?
- шаблон вводит пользователем, с тегами, такими как
[[contact.name]]
и тому подобное. - при сохранении, регулярное выражение преобразует их в переменные PHP, поэтому приведенный выше подстановочный знак становится
{$contact['name']}
в строке шаблона. - Мы также проверяем наличие чего-либо, что может быть преобразовано в доступную переменную из суперглобальной области, поэтому
[[_SERVER]]
,[[GLOBALS]]
и т. Д., А также[[this
все не разрешены и зарегистрированы как попытки взлома. - Другие символы, имеющие особое значение в строке с двойными кавычками (
$
,"
и\
), также экранированы. - процесс генерации выглядит следующим образом:
- поколение - метод класса, который запускается. Единственная переменная, которая проходит, равна
$contact
, которая представляет собой массив. - строка шаблона считывается в другую локальную переменную (в данном случае
$__templateString
). Пользователи могут теоретически получить доступ к этой переменной в своих шаблонах, но на самом деле это не имеет значения, если они это сделают - это не риск для безопасности, просто тупой. - Код для создания шаблона является то просто
eval('return "' . $__templateString . '";');
- поколение - метод класса, который запускается. Единственная переменная, которая проходит, равна
Все отверстия я здесь отсутствует? Я почти уверен, что единственными потенциальными рисками являются вопросы доступа к сфере видимости, и я думаю, что я накрыл все свои базы там.
Я не знаю, но такие места, как кододелат, делают это. Я часто задавался вопросом, как это сделать. –
@Dagon https://github.com/Viper-7/Deployable-PHP-Codepad chrooting и заблокированные системные разрешения для пользователя, что сценарий выполняется как. Это намного сложнее, чем «eval». – deceze
Если вы хотите что-то быстрое и безопасное, вы должны использовать [handelbars] (http://handlebarsjs.com/) и скомпилировать свой PHP с помощью [hiphop] (https://github.com/facebook/hiphop-php/), нам действительно не нужно другое умение. – rook