Безопасное исполнение PHP кода в шаблоне

Статус
В этой теме нельзя размещать новые ответы.

SKYNET74

Постоялец
Регистрация
11 Июл 2016
Сообщения
146
Реакции
20
Здравствуйте, собственно может быть кто то сталкивался, гугления и хабрления особо ник чему толковому не привели, кроме нескольких библиотек на гитхабе, которые работают ну очень медленно, жрут ну очень много памяти, и уже давно не обновлялись. Работают на основе PHP токинайзера.

Задача сделать шаблонизатор с PHP подобной логикой, но при этом безопасный для самого сайта (в случае если злоумышленник как то попадёт в админку, и вставит в шаблон опасные функции).

Стадии работы:
- Загружаем шаблон (из файла или переменной)
- Проверяем сгенерированный PHP кеш
- Если кеш есть, исполняем
- Если кеша нет, запускаем парсер синтаксиса для преобразования в PHP код
(Вот на данном момент после преобразования нужно проверить что бы в сформированном PHP коде не было недоступных функций, которые втихоря сольют куда надо конфиги и всё что угодно)
- Исполняем готовый PHP код
- Пишем результат в перменную

Собственно сам .tpl файл представляет из себя подобие PHP кода и в какой то мере напоминает шаблонизатор uCoz (но более функциональный), аля:
<?if($USER_ID$ == 1)?>
Вы пользователь №1
<?elseif($USER_ID$ == 2)?>
Вы пользователь №2
<?elseif($USER_ID$ == 3)?>
Вы пользователь №2
<?else?>
Вы неизвестный пользователь
<?endif?>

Подключается через include, вывод захватывается в буфер и возвращается в переменную которая содержит отработанный шаблон (с учётом установленных для него переменных и условных операторов).
Ещё бы не плохо ловить синтаксические ошибки и не вываливать их в вывод.

Может у кого то есть идеи по реализации?

*На текущий момент есть рабочая версия, но не решены вопросы с фильтрацией функций шаблона, а так же с захватом ошибок синтаксиса.*


PS: Рассматривал Smarty, но там слишком много функционала + некоторые нужные мне вещи придётся реализовывать на костылях храмого PHP. Да и после проведённых тестов он оказался этак помедленней своего собственного варианта.
PS2: Думаю Горбуша может что то подсказать тут...
PS3: Никто не в курсе, PHP OPcache кеширует ОП-код только в .php файлах, или в любых других которые обрабатываются php? т.е. играет ли роль расширение файла?
 
Последнее редактирование:

nejtr0n

Гуру форума
Регистрация
24 Янв 2014
Сообщения
129
Реакции
82
Большинство шаблонизаторов, на сколько мне известно, не предполагают ограничение функционала (например отключение php), так как это является их фичей.
Можно взять например Для просмотра ссылки Войди или Зарегистрируйся, и выпилить из него всё лишнее.
Ну или написать своё. Задача по сути тривиальная, но имхо сделать это безопасно очень сложно.
 

SKYNET74

Постоялец
Регистрация
11 Июл 2016
Сообщения
146
Реакции
20
Да в том то и дело что возится с такими монстрами и выпиливать всё что не нужно это ещё та задачка, да и синтаксис переделать не везде получится.
Я потестировал несколько популярных шаблонизаторов, везде скорость страдала, либо получаемый PHP код был довольно мусорным, либо они были очень тяжелыми и там куча не нужного подгружается.
Мой же как минимум в несколько раз быстрее, за счёт того что там нет не нужного функционала.

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

Видимо всё таки PHP токинайзер единственный вариант, но это очень жестко по ресурсам и сложности реализации.
 
Последнее редактирование:

Nei

Nosce te ipsum
Команда форума
Модератор
Регистрация
5 Сен 2009
Сообщения
688
Реакции
603
А можно подробней зачем вообще php в шаблонах? Зачем мешать в кучу php и html-код?
В том же Smarty действительно есть возможность вставлять php-код в шаблоны, но пользоваться такой возможностью я бы не рекомендовал, и по факту довольно редко встречаются такие вставки, а такого варианта, чтобы без php-кода в шаблонах нельзя было обойтись, я вообще не встречал.
 

SKYNET74

Постоялец
Регистрация
11 Июл 2016
Сообщения
146
Реакции
20
Там не PHP в шаблонах, а PHP подобная логика, которая после парсинга превращается в PHP код и при последующей компиляции уже просто исполняется PHP код, и задача стоит обезопасить шаблон от возможных вставок именно PHP кода.
upd
Впринципе написал что хотел, придётся похоже от некоторого синтаксиса отказаться, но зато скорость исполнения такая, что и смарти проигрывает.
Безопасность обеспечил токинайзером, который проходит по коду только в первый раз при создании скомпилированной версии шаблона, памяти жрёт прилично, но другого решения видимо нет.
 
Последнее редактирование модератором:

latteo

Эффективное использование PHP, MySQL
Регистрация
27 Фев 2008
Сообщения
1.603
Реакции
1.565
Мой же как минимум в несколько раз быстрее, за счёт того что там нет не нужного функционала.
А так же скорее всего не учтена куча ошибок, на которых другие уже набили шишки.
Если хотите разработать свой быстрый и безопасный шаблонизатор, то хорошо бы изучить несколько имеющихся популярных и их issue на гитхабе. Наверняка найдёте много интересных моментов...

Smarty сильно устарел, сейчас twig популярен и во фреймворках можно микрошаблонизаторы найти.
 

SKYNET74

Постоялец
Регистрация
11 Июл 2016
Сообщения
146
Реакции
20
А так же скорее всего не учтена куча ошибок, на которых другие уже набили шишки.
Если хотите разработать свой быстрый и безопасный шаблонизатор, то хорошо бы изучить несколько имеющихся популярных и их issue на гитхабе. Наверняка найдёте много интересных моментов...

Smarty сильно устарел, сейчас twig популярен и во фреймворках можно микрошаблонизаторы найти.
На текущий момент свою задачу он выполняет, ошибок в проверке шаблона на доступные функции нет, я протестировал разные варианты, перехват критических ошибок парсера PHP никак не сделать, по этому я отслеживаю в ядре CMS возникающие ошибки, и вывожу потом шаблон для 5xx с подробным описанием для пользователя и для администратора.
Правда OPcache себя странно немного ведёт с ним (кеширует файл шаблона со второго раза), но профита больше чем проблем от него, так что оставил как есть.

Насколько я понимаю, исключениями же никак не отработать E_PARSE?
 

latteo

Эффективное использование PHP, MySQL
Регистрация
27 Фев 2008
Сообщения
1.603
Реакции
1.565
Насколько я понимаю, исключениями же никак не отработать E_PARSE?
Через register_shutdown_function можно узнать, что была E_PARSE и записать в лог или еще что-то хорошее сделать Для просмотра ссылки Войди или Зарегистрируйся
Это часто в фреймворках встречаю.

Выполнить проверку синтаксиса можно запустив файл из консоли с параметром -l:
PHP:
php -l parse.php
можно попробовать в этом направлении поэкспериментировать.

И через расширения есть еще такое Для просмотра ссылки Войди или Зарегистрируйся
 

SKYNET74

Постоялец
Регистрация
11 Июл 2016
Сообщения
146
Реакции
20
Через register_shutdown_function можно узнать, что была E_PARSE и записать в лог или еще что-то хорошее сделать Для просмотра ссылки Войди или Зарегистрируйся
Это часто в фреймворках встречаю.
Именно она и используется у меня, но только она перехватывает все события, не только ошибки в шаблоне, и выводит отдельный шаблон под это дело.

Интересует именно вариант перехвата в шаблоне, что бы отработка кода продолжилась дальше, а вместо шаблона с ошибкой, вывести HTML комментарий с подробностями, но судя по всему в PHP так не получится.

runkit я смотрел, хотел вообще выполнять код шаблона в песочнице, но этот вариант не подошёл.
Проверку на ошибки синтаксиса сделать можно в виде опции, т.к. пользы от runkit_lint не особо много, вот возвращала бы она подробности найденных ошибок, или хотя бы последней ошибки в коде, можно было бы сделать полноценную проверку синтаксиса шаблона, перед его фактическим сохранением в файл.
Через консоль проверять не вариант, exec'а почти нигде нет, и очень не безопасно его разрешать.

PS: У вас не будет "очень хитрого и мерзопакостного" PHP кода для проверки шаблонизатора? Хочу безопасность потестировать у него.
Только без eval, т.к. это уже другая история, и функция eval запрещена по умолчанию.
 

latteo

Эффективное использование PHP, MySQL
Регистрация
27 Фев 2008
Сообщения
1.603
Реакции
1.565
PS: У вас не будет "очень хитрого и мерзопакостного" PHP кода для проверки шаблонизатора? Хочу безопасность потестировать у него.
Только без eval, т.к. это уже другая история, и функция eval запрещена по умолчанию.

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