Безопасность MODX, часть 2 - использование @ привязок
Это вторая часть доклада с конференции MODX Meetup Moscow. С первой частью про обход фильтрации MODX тегов можете ознакомиться тут.
А теперь давайте перейдем к другой потенциальной проблеме безопасности — @ операторы в ТВ параметрах. Если о MODX тегах (про которые я рассказывал в первой части) знают все и кто-то даже пытаются их как-то фильтровать, то ситуация с ТВ резко меняется. Очень часто можно встретить решения, когда через какую-то форму на сайте создаются ресурсы в дереве документов. Как правило, подобную реализацию используют для сбора отзывов. Пару лет назад, мне для аудита безопасности предоставили сайт, на котором каждый заказ это отдельный документ.
Так вот опасность подобной реализации состоит в том, что @ операторы можно использовать не только в качестве “значения по умолчанию”, но еще и в качестве значения в каком-нибудь документе.
Чтобы вы точно поняли о чем я говорю — предлагаю посмотреть на демо-сайт.
Там есть документ (id = 5) в котором присутствует вывод ТВ параметра [[*checkpoint]]. При чем этот ТВ не связан ни с одним шаблоном, но несмотря на это, в базе значений ТВ параметров — modx_site_tmplvar_contentvalues хранится
На реальных сайтах, где используются визуальные редакторы и куча ТВ параметров, без мониторинга базы не найти закладку.
Но если выполнение произвольного кода через EVAL привязку можно отключить воспользовавшись системной настройкой allow_tv_eval, то другие — @ операторы уже не отключаемые. А именно
В случае же, если вы производите аудит безопасности или чистите сайт от вирусов — проверяйте значения по умолчанию у ТВ. Но самое главное, проверяйте таблицу значений ТВ параметров. Сделать это можно с помощью запросов
Ну вот мы и добрались до самой латентной уязвимости.
Представьте следующую задачу: необходимо реализовать каталог, в котором можно будет переключиться с табличного варианта отображения на блочный или еще какой-нибудь.
Есть 2 варианта реализации подобного функционала — создать 2 разных страницы. Или принимать способ отображения через GET параметр. Выбирая второй способ можно допустить фатальную ошибку — ожидать имя чанка, при этом не задав white-лист.
Вот код уязвимого сниппета (используется getResources, но ничего не изменится если вместо него будет pdoResources):
На первый взгляд ничего критичного. Но если вспомнить про поддержку inline шаблонов в различных сниппетах. А потом еще узнать про возможность загружать шаблоны из файла через оператор @FILE. То уязвимость становится очевидной — мы имеем дело с чтением произвольных файлов (документ с id = 6 на демо-сайте). Поэтому ни в коем случае нельзя давать пользователям право влиять на способ отображения, если вы не определили заранее список поддерживаемых чанков.
@ операторы в ТВ параметрах
А теперь давайте перейдем к другой потенциальной проблеме безопасности — @ операторы в ТВ параметрах. Если о MODX тегах (про которые я рассказывал в первой части) знают все и кто-то даже пытаются их как-то фильтровать, то ситуация с ТВ резко меняется. Очень часто можно встретить решения, когда через какую-то форму на сайте создаются ресурсы в дереве документов. Как правило, подобную реализацию используют для сбора отзывов. Пару лет назад, мне для аудита безопасности предоставили сайт, на котором каждый заказ это отдельный документ.
Так вот опасность подобной реализации состоит в том, что @ операторы можно использовать не только в качестве “значения по умолчанию”, но еще и в качестве значения в каком-нибудь документе.
Чтобы вы точно поняли о чем я говорю — предлагаю посмотреть на демо-сайт.
Там есть документ (id = 5) в котором присутствует вывод ТВ параметра [[*checkpoint]]. При чем этот ТВ не связан ни с одним шаблоном, но несмотря на это, в базе значений ТВ параметров — modx_site_tmplvar_contentvalues хранится
@EVAL phpinfo();
И при просмотре страницы, код успешно выполняется.На реальных сайтах, где используются визуальные редакторы и куча ТВ параметров, без мониторинга базы не найти закладку.
Но если выполнение произвольного кода через EVAL привязку можно отключить воспользовавшись системной настройкой allow_tv_eval, то другие — @ операторы уже не отключаемые. А именно
- @DIRECTORY — Получение списка файлов в папке
- @FILE — Чтение произвольных файлов
- @SELECT — Выполнение запросов. При чем знать префикс таблиц вовсе не обязательно. Запросы можно строить используя плейсхолдеры [[+DBASE]] и [[+PREFIX]].
В случае же, если вы производите аудит безопасности или чистите сайт от вирусов — проверяйте значения по умолчанию у ТВ. Но самое главное, проверяйте таблицу значений ТВ параметров. Сделать это можно с помощью запросов
SELECT * FROM modx_site_tmplvar_contentvalues as stc WHERE stc.`value` REGEXP "^[[:space:]]*@";
# или
SELECT * FROM modx_site_tmplvar_contentvalues as stc WHERE trim(stc.`value`) LIKE '@%';
Найти значения ТВ параметров, которые имеют потерянные связи с ресурсами или шаблонами, можно при помощи запросаSELECT stc.id, sc.id as content_id, stc.`value` as tv
FROM modx_site_tmplvar_contentvalues as stc
LEFT JOIN modx_site_content as sc ON sc.id = stc.contentid
WHERE NOT EXISTS (
SELECT tmplvarid FROM modx_site_tmplvar_templates as stt WHERE stt.templateid = sc.template AND stc.tmplvarid = stt.tmplvarid;
)
x@ операторы в шаблонах
Ну вот мы и добрались до самой латентной уязвимости.
Представьте следующую задачу: необходимо реализовать каталог, в котором можно будет переключиться с табличного варианта отображения на блочный или еще какой-нибудь.
Есть 2 варианта реализации подобного функционала — создать 2 разных страницы. Или принимать способ отображения через GET параметр. Выбирая второй способ можно допустить фатальную ошибку — ожидать имя чанка, при этом не задав white-лист.
Вот код уязвимого сниппета (используется getResources, но ничего не изменится если вместо него будет pdoResources):
$tpl = $modx->getOption(
'tpl',
$_REQUEST,
$modx->getOption('tpl', $scriptProperties, 'DefaultChunk')
);
return $modx->runSnippet('getResources', [
'parents' => 1,
'tpl' => $tpl
]);
На первый взгляд ничего критичного. Но если вспомнить про поддержку inline шаблонов в различных сниппетах. А потом еще узнать про возможность загружать шаблоны из файла через оператор @FILE. То уязвимость становится очевидной — мы имеем дело с чтением произвольных файлов (документ с id = 6 на демо-сайте). Поэтому ни в коем случае нельзя давать пользователям право влиять на способ отображения, если вы не определили заранее список поддерживаемых чанков.
Поблагодарить автора
Отправить деньги
Комментарии: 10
Очень значительно. Пойду переваривать информацию
А я как раз задумывался и не мог понять почему у mFilter2 реализация разных шаблонов вывода сделана как она сделана, т.е. в GET передается &tpl=1, &tpl=2 и так далее
@EVAL уже выпилен в 3.x, к слову, но совет «включать голову» актуален всегда.
Эффект от allow_tv_eval почти тот же. Но там и без @EVAL хватает операторов
Интересно, зачем? Прикрываться безопасностью — глупо, имея менеджерский доступ к админке можно получить суперпользователя десятками способов которые успешно перешли из REVO в MODX 3. Уже 100500 раз говорилось что если хотите себя обезопасить — делайте для менеджеров свою админку. Выпилив @EVAL ничего не изменилось, а вот удобство убавили в разы. Я лично через @EVAL генерировал динамические возможные значения тв поля
А как тогда теперь задавать динамические возможные значения для тв? Неужели вешать плагин на пререндер?
Есть 2 варианта реализации подобного функционала — создать 2 разных страницы. Или принимать способ отображения через GET параметр.
Ну почему же только две, это вы придумали две.
Обычно это делает через куки и не нужно никаких get параметров
Если вы решили показать какой умный, то не удалось
1) $_REQUEST это GET/POST/COOKIE
2) Подменить данные в кукисах так же просто, как и в GET
Еще вопросы?
1) $_REQUEST это GET/POST/COOKIE
2) Подменить данные в кукисах так же просто, как и в GET
Еще вопросы?
Евгений, вы слишком напряжены)
Я не хотел никому демонстрировать, какой умный ибо чаще получается наоборот.
Но прочтите что я написал, там ни слова о подменах кук и безопасности.
Я просто уточнил, что способов при помощи которых на сайте можно переключить вид карточек товара больше чем 2 указанных вами и привел пример третьего.
Я не хотел никому демонстрировать, какой умный ибо чаще получается наоборот.
Но прочтите что я написал, там ни слова о подменах кук и безопасности.
Я просто уточнил, что способов при помощи которых на сайте можно переключить вид карточек товара больше чем 2 указанных вами и привел пример третьего.
Посмотрите внимательно пример уязвимого скрипта из статьи
$tpl = $modx->getOption(
'tpl',
$_REQUEST,
$modx->getOption('tpl', $scriptProperties, 'DefaultChunk')
);
Если я изменю текст с Есть 2 варианта реализации подобного функционала — создать 2 разных страницы. Или принимать способ отображения через GET параметр.на
Есть 2 варианта реализации подобного функционала — создать 2 разных страницы. Или принимать способ отображения через REQUEST параметр.Вы по прежнему будете доказывать, что способов больше чем 2?
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.