Cистематическая уязвимость сайтов, созданных на CMS 1С-Битрикс

Написать о систематических уязвимостях сайтов, созданных на коммерческих CMS, подтолкнул пост, в котором были описаны риски взлома «защищенных» CMS.

В этой статье основное внимание уделяется компрометации ресурсов по причине «человеческого фактора», а тема эксплуатации уязвимостей сайтов и веб-атак была обойдена предположением существования «неуязвимых» CMS. Предположение о существовании «неуязвимых» CMS, возможно, имеет право на существование, как пример, безопасность готового интернет-магазина «из коробки» на CMS 1C-Битрикс очень высока, и найти более-менее серьезные уязвимости кода «коробочной версии» вряд ли удастся.

Другое дело безопасность конечного продукта, созданного на такой CMS, и самое главное, систематика проявления уязвимостей высокого уровня угроз у этих сайтов. Исходя из нашей практики по обеспечению безопасности сайтов (компания InSafety), а также статистики, которую мы собираем по уязвимостям платформ (CMS), не менее чем у пятидесяти процентов сайтов, созданных на платформе 1С-Битрикс c личными кабинетами пользователей, существует возможность эксплуатации хранимых XSS-атак.

Платформа: CMS 1C-Битрикс 15.0 и выше
Угроза безопасности: хранимая XSS-атака
Систематика: не менее 50% сайтов с личными кабинетами пользователей

Уязвимость кода, позволяющая эксплуатацию XSS атаки, заключается в недостаточной фильтрации данных полей формы регистрационной информации личного кабинета пользователя ресурса, которые передаются в БД.

Пример

Разработчик сохраняет данные, например, имя пользователя из $_REQUEST, через API Битрикса, то они не фильтруются полностью, и тэги сохраняются. Например, передаем строку в поле формы «имя» ЛК пользователя сайта:

test"><a href='#'><img src='http://insafety.org/img/xss2.jpg'/></a><p

image

Данные передаются через обычный input в $_POST['name'] и далее в $USER->Update, например, так:

$USER->Update($USER->GetID(),array(
'NAME' => $_POST['name'],
));

HTML-код не будет санирован и будет запомнен в имени пользователя «как есть». Скриншот админки сайта:

image

Результат:

image


Этот пример наглядно демонстрирует наличие угрозы безопасности

В предложенной демонстрации существовании угрозы, было показано внедрение HTML кода, а не JS, что предполагает типовая XSS-атака. Это обусловлено тем, что у большинстве сайтов, разработанных на CMS 1C-Битрикс, попытку внедрения JS-кода заблокирует фильтр проактивной защиты.

Внедрение большинства синтаксических тегов HTML кода, проактивной защитой CMS 1C-Битрикс не фильтруется. Такая демонстрация обнаружения уязвимости кода абсолютно безопасна и наглядна. В случае, когда фильтр проактивной защиты 1С-Битрикс по какой-то причине отключен, вышеописанная уязвимость кода позволяет эксплуатировать хранимые XSS-атаки в «классической» реализации.

Уровень угрозы безопасности для сайта от внедрения любого (будь то JS или HTML) несанкционированного кода, как и его вывода без должной фильтрации, крайне высок.

По понятным причинам, в этой статье не предлагаются варианты реальной эксплуатации атаки, как с включенным, так и с отключенным фильтром проактивной защиты.

Защита от XSS-атаки


Защитить свой сайт от возможности эксплуатации XSS атаки достаточно просто. Для этого следует фильтровать входные и выходные данные путем экранирования символов и преобразования спецсимволов в HTML-сущности. В php это можно сделать с помощью функций htmlspecialchars(), htmlentities(), strip_tags().

Пример:

$name = strip_tags($_POST['name']);
$name = htmlentities($_POST['name'], ENT_QUOTES, "UTF-8");
$name = htmlspecialchars($_POST['name'], ENT_QUOTES);

Кроме этого следует явно указывать кодировку страниц сайта:

Header("Content-Type: text/html; charset=utf-8");

Способов защиты от XSS атак множество, к примеру, существуют варианты запрета на передачу кавычек и скобок (фильтрация данных по черному списку) на уровне конфигурации веб-сервера.

Пример для NGINX: (запись в конфигурационный файл)

location / {
	if ($args ~* '^.*(<|>|").*'){
	return 403; 
	}
	if ($args ~* '^.*(%3C|%3E|%22).*'){
	return 403;
	}
}

Для веб-сервера Apache это будет запись в файл .htaccess:

RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} (<|>|"|%3C|%3E|%22) [NC,OR]
RewriteRule ^{правило} 

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

Заключение


Вышеозначенная угроза безопасности на веб-приложения, является наиболее популярной и известной атакой. Про XSS атаки и защиту от них, написано тысячи статей и публикаций.

В практике нашей компании уязвимость к XSS атакам личных кабинетов пользователей была обнаружена осенью 2015 года. Весною 2016 года наша статистика уязвимых сайтов на CMS 1С-Битрикс явно указывала на наличие возможности эксплуатации атаки у более 50% процентов исследуемых сайтов. В апреле 2016 года, понимая, что уязвимость кода в этом разделе носит системный характер, мы передали всю информацию по угрозе безопасности в компанию Битрикс. Сотрудники компании Битрикс приняли информацию, сообщив в обратной связи, что приняли меры, исправив документацию к системе. Несмотря на принятые меры, вышеописанная угроза безопасности для сайтов на 1С-Битрикс остаётся крайне актуальной на сегодняшний день.

Надеюсь, что эта информация будет полезной для разработчиков и владельцев сайтов, созданных на платформе 1C-Битрикс.

Нужно понимать, что эксперименты с безопасностью чужих сайтов, не говоря о эксплуатации атаки в криминальных целях, может повлечь уголовную ответственность. Вся информация по угрозе безопасности сайтов, в этом посте, предоставлена с целью повышения общего уровня ИБ конечных продуктов на платформе 1C-Битрикс.
Метки:
Поделиться публикацией
Комментарии 65
  • +4
    Ну вставка картинки еще не выполнение произвольного javascript сценария, так что класс атаки другой :)
    • 0
      Автор лишь показал уязвимое поле (туда можно пихнуть что угодно, вплоть до целевого сплоита). И зря вы думаете, что картинка со стороннего ресурса это абсолютно безопасно — как минимум с ее помощью можно успешно собирать статистику о пользователях сайта.
      • +1
        Ну не совсем что угодно, у битрикса ж есть небольшой waf на xss, так что я не уверен, что можно вставить хоть какой-либо js. А картинку можно и в комментарии вставить (и собирать статистику о пользователях).
        • +1
          Теоретически, если обойти waf, то да, возможно xss, а для битрикса это вдвойне опасно, так как есть выполнение произвольного кода из коробки (в админ панели). Но это — нет.
          • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      Экранирование и преобразование символов считаю правилом хорошего тона. И не важно на основе какой CMS ты пишешь
      • 0
        Думаю экранирование и преобразование символов должно быть дейстием по умолчанию для фреймворка. Которое если надо, можно в конкретном месте выключить.
        • 0
          В статье идет речь об обработке с помощью API данных. Поэтому тут разработчик должен быть внимательным
          • 0

            Абсолютно согласен с AntonioLeavez, нам, как разработчикам на CMS 1С-Битрикс, важно получать актуальную информацию по возможным проблемам разработанных и\или разрабатываемых проектов на 1С-Битрикс с точки зрения безопасности, т.к. данная тема всё больше становиться актуальной и несет за собой дополнительные риски для разработчиков при взаимодействии с Заказчиком\Клиентом.

            • 0
              Например в других фреймворках, не буду называть каких, дабы не было холиваров, что бы вывести в html переменную без экранирования символов надо добавить дополнительные команды. А как неэкранированные переменные передать в orm вообще не представляю. Разве что через raw запрос. Но тут уж надо думать головой. За то я знаю, что если я действую стандартными методами, они априори безопасны. Откуда бы не пришли данные.
              Экранировать на входе — ну тут правда вопрос. Согласен что сами данные на входе опасности не несут, ее несет обрабатывающий код.
        • +6
          $name = strip_tags($_POST['name']);
          $name = htmlentities($_POST['name'], ENT_QUOTES, «UTF-8»);
          $name = htmlspecialchars($_POST['name'], ENT_QUOTES);

          Что это за кусок бреда?

          Потом люди читают такие статьи и пишут свои битриксы, где дырка на дырке.
          • 0
            Как, на Ваш взгляд, правильно?
            • +5
              Правильно понимать, что вообще происходит и действовать в соответствии с этим.

              А люди не понимают, но они где-то краем уха слышали про какие-то плохие символы, которые надо фильтровать. И они фильтруют всеми подряд функциями какие найдут, вырезают зачем-то теги и РЕЖУТ КАВЫЧКИ ВО ВХОДНЫХ ДАННЫХ СРЕДСТВАМИ СЕРВЕРА!!! Капец.

              Нет плохих данных, никакие данные сами по себе навредить не могут.
              Только код, который обрабатывает эти данные.
              Так и фильтровать/экранировать нужно только в момент обработки и только так, как эти обработка предполагает.

              • +4
                Человек прав. Подобный подход «бездумной» комбинации фильтрующих функций сам по себе может создать баг, и лишь говорит о не компетенции советующего в данном вопросе. К сожалению, не все кулхацкеры умеют что-то тольковое советовать в разработке и обеспечении безопасности.
                Если контекст вывода — html, то фильтровать надо при обработке функцией htmlspecialchars с нужной комбинацией флагов, в зависимости, опять-таки, от контекста использования конкретно этих данных в конкретном месте приложения.
              • 0
                При записи в бд каких либо данных от пользователя фильтроваться должно от инъекции.
                При выдаче результата из базы должны экранироваться теги.
                Это конечно я «грубо», иногда зависит от ситуации, но для первого правила должно быть именно так.
                • 0
                  Кстати, в php есть замечательная функция filter_var которая может как в валидацию данных так и в их очистку с нужными флагами.
              • +1
                Вопрос автору: на каком решении Вы тестировали данную уязвимость? Попробовал в Битрикс-лаборатории, у поля «NAME» у пользователя ограничение в 50 символов — Ваш HTML в принципе режется при добавлении (как Вы тестировали?). Но даже если его сократить, то все равно изображение упорно отказывается отображаться ))
                • 0
                  Конечно, существуют ограничения, которые не позволят реализовать и эксплуатировать атаку.
                  Суть проблемы в том, что для огромного количества сайтов, созданных на платформе 1С-Битрикс — эта уязвимость актуальна.
                  Кроме этого, в апреле, я передал всю информацию в Битрикс.
                  Естественно, на их ресурсах, этой проблемы нет.
                  • 0
                    Просто интересно, а что могут сделать в Битриксе?
                    Их стандартные компоненты этой уязвимостью не страдают. В админке кстати тоже.
                    Уязвимы только сайты, которые работают напрямую с API (моделью), минуя стандартные компоненты (контроллеры) и вьюхи (шаблоны). И при этом не фильтруют данные.
                    Т.е. криворукие быдлокодеры накосорезили, но виноват, разумеется, Битрикс.
                    Самое смешное, что Битрикс ничего в этом случае сделать не может. Ещё раз, API — это модель, её задача хранить данные как есть, и в ней, вообще говоря, ошибок нет. Добавлять в неё фильтрацию, htmlspecialchars и т.п. — нельзя, это сломает вообще кучу всего.
                    • +1
                      Подавляющее число интеграторов Битрикс используют стандартные компоненты, в данном случае компонент регистрации. Вот что навскидку нашел в коде компонента:http://prnt.sc/c5x1x6 — уж не то ли это преобразование спецсимволов в HTML-сущности, о которых Вы пишете в статье? ;)

                      Сдается мне, кто-то захотел срубить кармы на врожденной неприязни у хабраюзеров к Битриксу ))
                      • 0
                        Карма — это хорошо, а предупредить разработчика о потенциально возможной проблеме — еще лучше.
                        В Битрикс эту проблему еще в апреле отправил, и меры были приняты, многое исправлено.
                        При всем этом, актуальность этой угрозы безопасности сохраняется и сегодня.
                        • 0
                          В апреле какого года? Этого? Тогда Вам будет интересно узнать, что файл, часть кода которого я предоставил на скриншоте датирован 22.10.2014. Сюрприз! ;)
                          • 0
                            В апреле этого года. Ваш файл еще не смотрел, отпишу в ветке по нему.
                        • 0
                          Подавляющее число т.н. «веб-студий» могут делать сайты на стандартных компонентах. Интеграторы в полном понимании этого слова практически никогда не встречаются с задачами, где можно обойтись штатными компонентами, и вынуждены использовать API. Для того API и предоставляется платформой — чтобы его использовать.
                          • 0
                            Т.е. «интеграторы в полном понимании этого слова» изобретают велосипеды вместо того, чтобы пользоваться готовыми решениями, упрощающими разработку, правильно я Вас понимаю? Теперь понятно, откуда ноги растут у расценок тру-интеграторов )))

                            Но речь не о том, что понимать под «интегратором», а что под «т.н. веб-студиями» (но попытку подмены тезиса я оценил, Вы молодец )), а в том, что в стандартных компонентах данные уже фильтруются, и уязвимости нет — проблема автором высосана из пальца. Ну а фильтровать данные в собственном решении Вам никто не запрещает
                            • 0
                              Где Вы видите подмену?
                              Все правильно написано.
                              В статье, я также обращаю внимание на то, что у готового интернет-магазина «из коробки» проблема отсутствует.
                              Но при разработке серьезных проектов, штатных компонентов недостаточно, используется API.
                              Проблема возникает именно в этом случае, и встречается крайне часто.
                              На счет «проблема высосана из пальца» — Ваше мнение.
                              • 0
                                Таким образом, из Вашей статьи и дальнейшего обсуждения следует:
                                • коробочные решения и системные компоненты защищены и уязвимость в них не проявляется
                                • API Битрикс позволяет разработчикам совершать ошибки при разработке собственных решений и компонентов
                                • Вывод: в API Битрикс существует уязвимость (уязвимость типа «недалекий разработчик», видимо)


                                Что интересно — криворукие разработчики встречаются на любой платформе, так почему именно Битрикс? Возможно потому, что просто очередную статью о фильтрации данных форм никто бы и читать не стал. Впрочем, как Вы верно заметили, это мое мнение, как и все, написанное мной ранее — нет нужды лишний раз это подчеркивать. ;)
                                • –1
                                  мне кажется, что читать из супер глобальных массивов это печаль… но Битрикс это поощеряет
                                  • 0
                                    Какое отношение данный факт имеет к предмету обсуждения?

                                    И кстати, в новом ядре стараются уйти от этой позорной практики, медленно, но все же пытаются. Так что «поощряет» — не совсем верное определение, скорее «поддерживает по инерции».
                                  • 0
                                    Все верно:
                                    1. У «коробки» Битрикс этой проблемы нет.
                                    2. API Битрикс действительно позволяет совершать ошибки разработчикам.
                                    3. На счет уязвимости типа «недалекий разработчик», не соглашусь с Вами.

                                    Дело в том, что изначально, в документации к API Битрикс:
                                    http://dev.1c-bitrix.ru/api_help/forum/developer/cforumtopic/getlist.php
                                    Были приведены примеры использования, а именно:

                                    while ($ar_res = $db_res->Fetch())
                                    {
                                      echo $ar_res["TITLE"]."<br>";
                                    }
                                    


                                    После того, как информацию по проблеме была предоставлена Битрикс, пример был «отредактирован»:

                                    while ($ar_res = $db_res->Fetch())
                                    {
                                      echo htmlspecialcharsbx($ar_res["TITLE"])."<br>";
                                    }
                                    


                                    Поэтому, я не согласен с Вами, только в части «криворуких разработчиков», а так, все верно.
                        • –2
                          боже ж ты мой, и за это еще платят
                          • 0
                            Предупрежден — значит вооружен. Согласен со stavinsky, экранирование должно быть сделано фреймворком по умолчанию.
                            • +2
                              Встречал как-то эксплуатацию подобной html инъекции в почте мейл.ру года 4 назад.
                              В письмо встраивался html + inline css код, который добавлял прозрачный слой с position:absolute на весь экран, обернутый в ссылку на фейк сайт злоумышленника.
                              Так, как слой перекрывал весь интерфейс почты, по любому клику в любом месте происходил редирект на фейк, который выглядел как страница логина в мейл.ру и невнимательный пользователь думал, что его просто выкинуло из сессии при входе в просмотр письма и клику например на «Входящие». Я к тому, что сценарии эксплуатации подобных вещей имеются, но немало зависит от контекста. В почте это было опасно.
                              • +4
                                А в шаблоне ЛК использовать htmlspecialchars религия не позволяет?

                                Данные в базе должны храниться в том виде, в котором их ввел пользователь. Фильтровать только при выводе.
                                • +1
                                  В Битриксе всё ещё хитрее, специально для таких вот «специалистов».
                                  Данные фильтруются в контроллере («компоненте» в терминах битрикса), чтобы мега-разработчик шаблона выводил $arUser[«NAME»] и не задумывался о фильтрации. Но для тех случаев, когда нужны нефильтрованные данные, компонент добавляет специальный ключ $arUser["~NAME"], о котором знают не только лишь все.
                                  • 0
                                    я в курсе, только это не мешало мне по привычке фильтровать вывод в своих шаблонах/компонентах при работе с базой, это как на горшок ходить.
                                    • 0
                                      Абсолютно верно подмечено. Все пытался найти ссылку на документацию. Спасибо vanxant
                                    • 0
                                      Если писать на PHP, то Вы правы. Но чем круче фреймворк, тем больше от него ожиданий. Битрикс — не Laravel, а крайне мощная платформа, и, учитывая заявленный «Проактивный фильтр», требования к нему соответствующие.
                                      • 0
                                        Если битрикс — фреймверк, то где я могу найти описание как я могу использовать его компоненты в других проектах(не битрикс)? Вот например в symfony это реализовано так http://symfony.com/components
                                        • 0
                                          Мопед не мой (с). Часть Битрикса теперь официально именуется Bitrix Framework. Никто не запрещает не использовать админку Битрикса, не использовать никакие штатные компонента Битрикса и использовать Битрикс только в качестве фреймворка.
                                          • 0
                                            Часть Битрикса теперь официально именуется Bitrix Framework


                                            Ну именовать они могут как угодно, но это не означает что так и есть.

                                            Никто не запрещает не использовать админку Битрикса, не использовать никакие штатные компонента Битрикса и использовать Битрикс только в качестве фреймворка.


                                            Ну во первых это не тоже самое, с тем что я приводил для примера с symfony components. Во вторых, мне страшно представить, что будет если брать их сборник низкокачественного кода и что-то на нем делать.
                                    • +3
                                      Вообще то в битрикс есть авто-тесты кода которые укажут на то что используется не экранированный $_POST и посоветуют использовать функцию htmlspecialcharsbx
                                      • 0
                                        Если бы разработчики битрикса использовали нормальную архитектуру, то это бы позволило внедрить TDD который бы еще на этапе разработки исключал 85% — 95% багов и брешей безопасности. А данный костыль в виде «авто-тесты кода» не более чем «подорожник» который просто не способен качественно обработать кучи строк низкокачественного кода самого битрикса.
                                      • 0
                                        Функция есть, а авто-тесты не видят проблемы.
                                        • 0
                                          очень странно, я неоднократно встречался с такими проблемами на поддержке, через «Монитор качества» всегда находились подобные ошибки
                                          • 0
                                            Вы правы, проблемы обнаруживаются, но конкретно этот сюжет, авто-тест не отрабатывал.
                                            Возможно что-то изменилось в 16.5.
                                            В своей работе, я эту проблему встречаю у каждого второго сайта.
                                            • 0
                                              Если вручную запускать «Сканер безопасности» то подобные потенциальные XSS он успешно находит.
                                        • +1
                                          И при чем тут собственно Битрикс? Это не вина Битрикса, что разработчики не фильтруют входные данные.
                                          • +2
                                            Был как-то забавный случай: сайт на «1С-Битрикс: Корпоративный портал», форма загрузки файлов, все потенциально опасные расширения фильтровались, всё ок. Но. Заметил, что если в имя файла добавить, например, символ процента (%), то данный символ при загрузке заменяется на случайный символ [a-z]. Сделал 30 файлов (с запасом, ага) вида <1-shell.ph%>, загрузил в форму и получил один из файлов <1-shell.php>, т.е. получил шелл. Конечно, проблема еще в том, что было разрешено исполнение файлов из папки </upload/>. Это я к тому, что фильтрации расширений мало.
                                            Заголовок спойлера

                                            • 0
                                              Ничего себе! А когда это было?
                                              Из смешного, в последнее время, только обход фильтра по типу ononclick='JS', когда фильтр Битрикс синтаксически 'on' отрезал, для блокировки той-же XSS. Сейчас, конечно, фильтр проактивки стал достаточно серьезным.
                                              • 0
                                                Встретилось 2015 г. (Твит сделан гораздо позже)
                                                Версию Битрикса не скажу, к сожалению. Думаю, что не самая свежая на тот момент.
                                                • 0
                                                  Не надо версию, от греха подальше.
                                                  В Битрикс сказать можно, хотя на практике не все обновляются и т.д.
                                                  По этой платформе, у меня самого достаточно «непубличного» материала, в Битрикс отдаю, по мере обнаружения и его актуальности.
                                            • 0

                                              В ваших конфигах для веб-серверов не учтены частные случаи:


                                              • иногда люди заключают атрибуты тегов не в кавычки, а в апострофы
                                              • когда пользовательский ввод вставляется в генерируемый на серверной стороне js (запрета символа " явно недостаточно, надо добавить ' и { })
                                              • 0
                                                Конечно, все так. В статье приведен элементарный пример фильтрации по списку.
                                                • 0
                                                  Думаю, пользовательский ввод в генерируемый js надо вставлять через json_encode(), без всяких запрещающих правил.
                                                • 0
                                                  Учитывая что сайты на данной CMS редко обновляют в силу понятных причин, дырка будет жить очень долго.
                                                  • 0

                                                    DeLuxis, так это зависит от Владельцев или студий сопровождающие сайты\интернет-магазины, которым не безразлична безопасность собственных проектов.
                                                    К тому же, вариант устранения уязвимости, так же представлен в статье, нужно только воспользоваться предложенным решением, хотя именно это самое сложное, воспользоваться.....:)))))

                                                  • 0
                                                    1. Это не вина Битрикса, что разработчики не думают головой. Такое можно сделать везде.
                                                    2. htmlspecialchars и т.п. — не панацея от xss.
                                                    3. Часто нужно хранить сырые данные.
                                                    • 0
                                                      Никто не говорит про платформу Битрикс, как о источнике угрозы.
                                                      Выше, в комментариях я написал, что явилось (как один из вариантов) причиной появления систематики этой угрозы безопасности.
                                                      Если говорить о вышеописанной проблеме, то есть больше сомнения в целесообразности хранения этих данных «сырыми».
                                                      На счет защиты и панацеи, htmlspecialchars — является одним из способов защиты от XSS.
                                                      • 0
                                                        1. Но предалагается, чтобы Битрикс что-то фиксил.
                                                        2. Один из способов, но не панацея. xss успешно пролезают через него, если понадеятся только на него.
                                                        3. Ну в этом случае сырые данные может не нужны. А в другом нужны.
                                                        Допустим name — это логин.
                                                        Тогда для фильтрации обработку нужно будет использовать еще в фильтре.
                                                        А если мы потом изменим второй параметр в htmlspecialchars($_POST['name'], ENT_QUOTES);
                                                        Или захотим вообще вырезать hmtl.
                                                        Или нужно пропустить часть html — ссылки, списки, рисунки (в комментрии пользователя к статье).
                                                        :)
                                                      • 0
                                                        Первый попавшийся интернет магазин на битриксе. http://joxi.ru/Vm6xjdghxed6bA. Встроенный сканер не помог.
                                                        • 0
                                                          Встроенный сканер и не поможет. Если данные, которые УЖЕ есть в БД читаются через API и выводятся на страницу, то что может сделать сканнер?
                                                        • 0
                                                          кидайте в меня ссаными тряпками, но мы ждем имя, так пусть будет имя, все, что не разрешено — запрещено:
                                                          preg_match('/^[-_a-zа-я0-9]{3,100}$/ui',$_POST['name'])
                                                          

                                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.