Смарти: несколько слов о безопасности
Разработчики Смарти не обошли и проблему безопасности в своем проекте. Под безопасностью здесь конечно подразумевается сфера шаблонов, т.е. мы обезопасиваем использование шаблонов, а не скриптов, которые их вызывают. |
А что там вообще надо обезопасивать и как мы можем нарушить безопасность какого-нибудь проекта с помощью шаблонов?
Допустим, я - интегратор. Я участвую в разработке какого-то крупного коммерческого проекта, где используется всеми любимый (и мной в том числе ) Smarty. Если я интегратор, мне не обязательно лезть в php-скрипты. Главное - мне нужен доступ к директориям картинок, css-файлов, js-файлов и шаблонов, где я бы мог менять дизайн и т.п.
В шаблонах при отключенной или плохо настроенной безопасности я могу делать три небезопасных действия, начинающихся на букву В:
- вставлять php-код
- вызывать любые функции php в условных операторах {if}
- включать любые шаблонные файлы (из любой директории сервера) в другие шаблоны
Всего этого избежать можно, настроив Smarty должным образом. Теперь посмотрим, как же это возможно.
В объекте Smarty есть специальная переменная, которая отвечает за включение/отключение безопасности. Она так и называется - security:
$smarty->security = true; // включили безопасность
$smarty->security = false; // выключили безопасность
Ну вот мы включили безопасность. А что подразумевается под этой безопасностью. Я буду подразумевать это как набор некоторых правил, которые настраиваются.
Эти правила можно задать с помощью следующих переменных объекта Smarty:
- security_settings
- secure_dir
- trusted_dir
Действуют эти правила, как Вы уже наверняка поняли, только в случае, если security установлена в true. Итак, по порядку.
security_settings
У этой переменной есть несколько значений, которые можно устанавливать по-разному:
- PHP_HANDLING - проверять ли значения переменной $php_handling на безопасность
- IF_FUNCS - массив php-функций, которые можно использовать в конструкции {if}
- INCLUDE_ANY - принимать ли во внимание значение переменной secure_dir
- PHP_TAGS - можно ли в шаблонах использовать php-код между {php} и {/php}
- MODIFIER_FUNCS - массив разрешенных php-функций модификаторов переменных
- ALLOW_CONSTANTS - можно ли использовать в шаблонах константы, объявленные в вызвавшем скрипте с помощью define
PHP_HANDLING
Переменная $php_handling определяет, каким образом Смарти должен обрабатывать php-код, вставленный в шаблон (между и ?>). Если значение $php_handling равно SMARTY_PHP_ALLOW, то php-код в шаблоне будет выполнен. Если же значение равно SMARTY_PHP_REMOVE, то все php-теги будут удалены из шаблона (код не будет выполнен). Если SMARTY_PHP_QUOTE - весь php-код будет отображен как обычный текст (код не будет выполнен). Если SMARTY_PHP_PASSTHRU, то php-код будет в исходном тексте страницы, но не будет выполнен.
Так вот если мы установим
$smarty->security_settings[PHP_HANDLING] = true;
И если $php_handling был установлен в SMARTY_PHP_ALLOW, то Смарти изменит это значение на SMARTY_PHP_PASSTHRU.
IF_FUNCS
Если мы определим
$smarty->security_settings[IF_FUNCS] = Array(‘count’);
то в {if} будет разрешено использовать только php-функцию count.
INCLUDE_ANY
Если мы зададим значение
$smarty->security_settings[INCLUDE_ANY] = true;
то значение переменной secure_dir не будет учитываться. Иначе в массив $smarty->secure_dir нужно занести пути ко всем директориям, разрешенным в использование через директивы {include} и {fetch}.
PHP_TAGS
Если
$smarty->security_settings[PHP_TAGS] = true;
то выполнение php-кода в шаблонах с помощью {php}{/php} будет запрещена.
ALLOW_CONSTANTS
Чтобы разрешить использование конструкций типа {$smarty.const.MY_CONST}, нужно разрешить константы:
$smarty->security_settings[ALLOW_CONSTANTS] = true;
trusted_dir
Эта переменная-массив используется, чтобы задать список тех директорий, из которых возможен запуск php-скриптов с помощью {include_php}.
Резюме
Вот собственно и все, что касается безопасности в Смарти. При правильном подходе можно в меру ограничить возможности того, кто редактирует шаблоны. Только перед экспериментами не забудьте присвоить $smarty->security значение true