15 августа 2016 в 09:27

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-Битрикс.
Алексей Резников @inSafety
карма
13,0
рейтинг 0,0
Информационная безопасность
Самое читаемое Разработка

Комментарии (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 с нужной комбинацией флагов, в зависимости, опять-таки, от контекста использования конкретно этих данных в конкретном месте приложения.
        • +1
          В статье приведены функции php, а не их комбинация.
          Фильтрация не предполагает бездумных решений, Вы абсолютно правы.
      • 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'])
    

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