Безопасность

Урок 5 из 9

1 час

Немного теории

Одно из важных неявных нефункциональных требований при разработке сайтов на платформе «1С-Битрикс: Управление сайтом» — требование к безопасности разработки. Создавая публичный объект ИТ-инфраструктуры, надо помнить, что вместе с тем появляются риски недобросовестного его использования.

Главное правило безопасности — не доверять пользовательским данным. Под “пользовательскими данными” понимаются не только данные, введенные посетителем сайта в input-поля форм, но и все остальное: отправляемые им файлы, куки, заголовки http. Более того, даже понятие “пользователь” нужно трактовать максимально широко — если сайт интегрирован с учетной системой и забирает оттуда товары, а из веб-сервиса банка получает курс валют — их данные тоже нужно проверять по всей строгости.

Рассмотрим самые распространенные способы атаки на веб-сайт.

SQL code injection

Самой опасной считается атака на базу данных. Если злоумышленник сможет повлиять на SQL-запрос, он сможет получить, испортить или уничтожить данные. Чтобы обезопасить свои данные от этой атаки, необходимо тщательно фильтровать все, что поступает в SQL-запросы. Такая фильтрация производится в рекомендуемых для работы с БД API-методах, поэтому в документации и всех обучающих материалах об этом постоянно напоминают. Потому что в противном случае, при самостоятельных запросах в базу, вопрос безопасности полностью перекладывается на разработчика.

Поэтому добавление данных в Инфоблоки, HL-блоки и ORM-сущности нужно производить с помощью официальных методов Add, Update, Delete и GetList.

Но не любой API-метод можно считать абсолютно безопасным. Среди них есть и внутренние, которые разработчики оставили для себя и для широкого применения они не пригодны:

  • CDatabase::Add
  • CDatabase::PrepareInsert
  • CDatabase::PrepareUpdate
  • CDatabase::PrepareUpdateBind

Особенность таких методов в том, как в них передаются данные. Защита будет производиться, если данные передавать по реальным ключам, и будет отключена, если передавать данные в ключах с тильдой в начале названия колонки БД. Поэтому нельзя взять сырой массив $_POST и передать в качестве аргумента в такой метод.

Похожая ситуация с SqlExpression, который позволяет расширить условия фильтрации в ORM. Это API-метод с описанной документацией, но его нужно грамотно использовать. Практический пример мы разбираем в видео к данному уроку.

В то же время, особенно в контексте повышения производительности, собственные запросы к БД имеют право на существование. Если иного решения нет, то разработчик должен использовать следующие методы для каждой переменной, которую собирается передать в SQL-запрос.

  • CDatabase::ForSql
  • Bitrix\Main\DB\SqlHelper::forSql

Межсайтовый скриптинг/XSS

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

Но в конце текста обращения злоумышленник может открыть тег <script> и написать произвольный javascript-код. Например, похитить куки сотрудника техподдержки или подменить часть контента страницы, чтобы увести сотрудника на другой сайт. Это и есть XSS-атака или межсайтовый скриптинг.

Ни в коем случае нельзя полагаться на клиентскую валидацию данных. Даже если в браузере написано правило, например, запрещающее вводить латинские символы, это правило можно отключить в панели разработчика почти в любом браузере или обойти, отправив сырой HTTP-запрос, минуя браузер. Поэтому под угрозой не только поля <textarea>, но и <select> и все типы <input>, в том числе и hidden.

Если сайт защищен от такой атаки, то js-код не будет выполнен, а о попытке обмана будет создана запись в журнале безопасности. Если защиты нет, то любой код злоумышленника будет выполнен.

Также вместо тега <script> злоумышленник может вставить ссылку <a> на свой сайт, в надежде, что по неосторожности или из любопытства кто-либо перейдет по этой ссылке. Тег <a> может быть дополнен атрибутами onclick, onfocus и подобными, в которых, опять же, будет javascript.

Для защиты от таких атак используются специальные функции PHP и платформы при сохранении данных в БД или при их выводе:

  • Для удаления тегов из строки: strip_tags, HTMLToTxt.
  • Для защиты параметров в url: urlencode.
  • Для вывода html как текста: htmlspecialchars, htmlentities, htmlspecialcharsEx, HtmlFilter::encode.

Если заранее известно, что в том или ином поле будет храниться число — вместо обработки текста можно применить intval или приведение к int.

Позже, при выводе данных из БД, стоит помнить про разницу методов GetNext и Fetch. Fetch работает быстрее и достает данные ровно в том виде, в котором они хранятся в таблице. GetNext подвергает данные обработке и защищает html-символы строк. Поэтому во многих системных компонентах вы могли видеть в $arResult дубли ключей, например, ~NAME и NAME. Разница в том, что по ключу NAME лежат обработанные безопасные данные, а в ~NAME — “сырые”, ровно в том виде, в каком хранятся в БД.

CSRF

Можно заставить браузер обратиться к произвольному сайту без ведома самого пользователя. Например, прислав ему картинку, src которой будет вести в административный раздел сайта, на котором у него активна сессия администратора. В таком случае, так как браузер авторизован, любой такой GET-запрос без дополнительных проверок будет интерпретирован как осознанное действие пользователя.

В случае с GET-запросами обычно вреда нет, но есть способ спровоцировать и POST-запрос, а это уже серьезная проблема.

Чтобы быть уверенным, что входящий HTTP-запрос действительно отправлен текущим пользователем по его инициативе, в платформе существует способ “подписать” каждый запрос. В качестве подписи используется значение, основанное на коде сессии пользователя.

Во всех POST-формах требуется разместить вызов функции bitrix_sessid_post, а перед обработкой формы достаточно вызова check_bitrix_sessid, чтобы убедиться, что в POST содержится та самая подпись.

Открытые редиректы

Злоумышленники могут атаковать сайт не только с целью кражи или порчи данных непосредственно из его БД. Используя атаку типа “открытый редирект”, они могут похитить самого пользователя и увести его на свой сайт.

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

Чтобы таких перенаправлений не было, нужно защищаться от XSS. Во-вторых, нужно грамотно использовать существующий в платформе механизм “Защита редиректов”. Вместо прямых ссылок на другие сайты потребуется выводить ссылку вида /bitrix/redirect.php?goto=<url> (или /bitrix/click.php , /bitrix/rk.php). Механизм “Защита редиректов” сам найдет на страницах гиперссылки и добавит к ним подпись, GET-параметр af, который станет меткой, что редирект выполняется осознанно и с разрешения платформы. В противном случае пользователь увидит предупреждение, что он уходит на другой сайт.

Особые угрозы

Переходя от общих угроз к частным, хотим отметить важность внимательного обращения с методом CAgent::AddAgent. Данный метод создает в планировщике PHP-задание, которое будет выполнено, когда сработает таймер. Первый аргумент name данного метода — полноценная строка кода, которая будет выполнена с помощью функции PHP eval(). Не существует универсальной функции, которая бы проверила значение этого аргумента и избавила его от кода злоумышленника, поэтому мы можем только дать рекомендацию никогда не создавать агенты на основании данных, полученных от пользователя.

Проактивная защита

Все инструменты, относящиеся к продвинутой предиктивной защите сайта от злоумышленников, собраны в платформе в модуле Проактивная защита. Обязательные для самостоятельного изучения инструменты:

  • Сканер безопасности

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

    Набор специализированных средств, которые выполняют фильтрацию трафика. Например, заметив в пользовательских данных тег <script> именно проактивный фильтр заменит его на строку <sc ript>. Фильтр можно настроить, чтобы он не мешал там, где такая бдительность может нарушить работу пользователей, но в большинстве случаев его действия оправданы.
  • Защита редиректов

    О которой мы уже рассказали ранее в этом уроке.
  • Защита сессий

    Позволяет перенести хранение сессий из файлов в БД и настроить частоту смены идентификаторов сессий. Частая смена идентификатора существенно затрудняет атаку на сайт, но может сказаться и на UX пользователя.
  • Контроль активности

    Способ борьбы с ботами и DDoS-атаками, защищает от чрезмерно активных пользователей, программных роботов, и попыток подбора паролей перебором.
  • Журнал вторжений

    Хранит логи всех событий, связанных с модулем.

Практика

В этом видеоуроке продемонстрируем несколько распространенных уязвимостей веб-приложений и рассмотрим средства защиты при их эксплуатации.

Большинство примеров будут показаны на компонентах, работающих с новой сущностью “Уведомления”, с которой мы познакомились в предыдущем уроке.

НЕ РАЗМЕЩАЙТЕ МАТЕРИАЛЫ ЭТОГО УРОКА В РАБОЧИХ ПРОЕКТАХ И НА ПУБЛИЧНЫХ ВЕБ-СЕРВЕРАХ!

Материалы содержат специально подготовленные примеры с грубыми ошибками в безопасности, которые будут продемонстрированы и исправлены в ходе урока.

Никогда не размещайте эти материалы в рабочих проектах и, тем более, на публичных веб-серверах. Используйте их только для обучения в рамках вашего личного учебного проекта на локальном веб-сервере.

Безопасность

45 мин