Наиболее известная уязвимость безопасности в веб-приложениях – это межсайтовый скриптинг (XSS). По оценкам, на данный момент он присутствует в более чем двух третях веб-приложений в интернете. Существует несколько способов снижения данного риска: через заголовок политики безопасности контента (CSP), проверку ввода и кодирование вывода. Требование кодировки вывода существует только для предотвращения XSS-атаки, а из-за большой распространенности данной уязвимости, несомненно, стоит добавить в приложение все три перечисленных средства защиты.
СОВЕТ. Добавление в приложение всех трех способов борьбы с XSS – отличный пример применения принципа «защиты в глубину».
Экранирование символа или значения означает удаление специальных полномочий, которые он имел бы, если бы выполнялся как код, а не рассматривался как часть данных (как и должно быть). Обычно экранирование осуществляется путем добавления обратной косой черты (\) перед соответствующим специальным символом.
Кодированием называется преобразование исходного формата значения согласно используемому стандарту (кодирование URL, кодирование base64, кодирование HTML). Кодирование можно легко обратить, поэтому его не следует путать с шифрованием или использовать вместо него. Целью кодирования является не защита кодируемого значения, а изменение его оригинального формата на нужный для использования. Например, если вы собираетесь вывести какую-нибудь информацию на экран, вам необходимо закодировать ее, используя соответствующую функцию (все современные платформы имеют такую функцию). Если значение, выведенное на экран, содержит вредоносный код (например, атаку межсайтового скриптинга), то при произведенной кодировке выходных данных будет выведено только текстовое значение, а не интерпретация (выполнение) кода в браузере в качестве JavaScript. Кодирование выходных данных обезвреживает код XSS-атаки.
Заповедь здесь, скорее всего, очевидна: кодируйте (и, если нужно, экранируйте) все выходные данные.
ПРИМЕЧАНИЕ. XSS – это особый вид инъекционных уязвимостей, поскольку при успешной атаке код (JavaScript) выполняется на стороне клиента (в браузере), тогда как большинство других уязвимостей данного типа выполняются на стороне сервера (на уровне интерпретатора, операционной системы и т. д.). Защита от XSS подразумевает сочетание проверки входных значений и кодирования либо экранирования выходных значений, в то время как все остальные инъекционные уязвимости зависят в основном от проверки ввода и настроек конфигурации на стороне сервера. Кроме того, XSS встречается чаще других серьезных типов уязвимостей в интернете. Таким образом, несмотря на то что XSS является одним из видов инъекционных уязвимостей, его всегда выделяют в отдельный класс уязвимостей.
Как уже говорилось ранее, каждая строка кода, взятая из библиотеки, платформы, плагина или другого компонента стороннего производителя, подвергает риску ваше приложение. Если приложение обращается, вызывает или использует часть небезопасного компонента, то оно само становится уязвимым. В зависимости от ситуации уязвимость может повысить даже неиспользуемая незащищенная строка кода в компоненте. Проверка сторонних компонентов на уязвимости – залог быстрого и легкого успеха в понимании уровня безопасности приложения. Устранение найденных проблем может потребовать времени и сил, но в значительной степени обеспечит защиту приложения, а потому этот пункт всегда включается в список требований к проекту и обслуживанию.
ИЗВЕСТНАЯ УЯЗВИМОСТЬ
Что значит «известная уязвимость»? По своему определению пользовательское программное обеспечение уникально. Каждая его часть – снежинка, и, следовательно, каждая новая уязвимость, которую можно в ней найти, неизвестна общественности. Программное обеспечение, которое не является пользовательским, часто называют просто программным обеспечением, как, например, операционная система или COTS. (COTS расшифровывается как Commercial/Customizable/Configurable Off The Shelf и буквально означает «Коммерческий/пользовательский/конфигурируемый готовый программный компонент».) Такое программное обеспечение может приобрести и установить любой желающий, и при этом оно обладает широкими возможностями конфигурирования. В качестве примера можно привести такие программы, как SharePoint, WordPress, Microsoft Office и Adobe Illustrator. В идеальном мире, когда тестировщик на проникновения, исследователь в области безопасности или другой «хакер» находит уязвимость в каком-либо программном обеспечении (пользовательском или нет), он сообщает о ней разработчику (это называется координированным раскрытием) или отмечает ее в программе Bug Bounty и получает вознаграждение. Если это не пользовательское программное обеспечение, то после сообщения об ошибке и выпуска исправления (обычно вместе с обновлением программного обеспечения) ошибка публикуется в интернете (например, в базе данных CVE Mitre) для всеобщего обозрения и таким образом становится «известной» уязвимостью. Версия программного обеспечения с неисправленной уязвимостью, обычно обнаруживающейся сканирующими автоматическими инструментами, называется «имеющая известную уязвимость».
После обнаружения, но до выпуска исправления ошибка в программном обеспечении, операционной системе или COTS-компоненте называется «нулевым днем», или «0-day»: тем самым отмечается, что ошибка еще не исправлена. Часто команды безопасности говорят об исправлениях, используя понятие количества дней с момента обнаружения ошибки, например «этой уязвимости 90+ дней, а мы до сих пор не исправили ее!», поэтому был выбран вариант «ноль».
ПРИМЕЧАНИЕ. Если в подкасте или в новостной статье говорится, что кто-то «сбросил день», это значит, что была обнародована информация об уязвимости в системе безопасности, для которой не существует известного исправления. Обычно это делается для оказания социального давления, чтобы заставить компанию выпустить исправление, или для демонстрации своих навыков исследователя безопасности. По моему мнению, всем, кто располагает информацией об уязвимости в системе безопасности, следует всегда сообщать о ней разработчику программного обеспечения, прежде чем публиковать ее на общественных ресурсах. Не для защиты компании, которая производит ПО, а для защиты пользователей. Они ни в чем не виноваты, и подвергать их риску противоречит цели и обязательствам индустрии информационной безопасности.
Существует множество средств, позволяющих проверить наличие уязвимостей в сторонних компонентах. В этой книге мы не будем рекомендовать конкретные инструменты или поставщиков, но предложим стратегические варианты применения таких средств. Первая стратегия заключается в использовании двух инструментов, если вы можете себе это позволить. Они проверяют разные базы данных разными способами и поэтому могут уловить разные проблемы. Вторая стратегия заключается в регулярном (ежедневном или, по крайней мере, еженедельном) сканировании репозитория кода, а также сканировании при каждом запуске кода в производство. Сканировать репозиторий необходимо потому, что даже в редко обновляемых приложениях все равно постоянно обнаруживаются новые уязвимости. Чем старше компоненты, внедренные в код приложения, тем больше времени было у исследователей безопасности и злоумышленников для изучения и поиска в них уязвимостей. Следует проводить сканирование при каждой публикации кода, поскольку вы (или ваши коллеги), не зная, могли добавить в него новый компонент или обновить уже имеющийся компонент до версии, в которой есть известная уязвимость. Включение проверки на наличие уязвимостей в CI/CD-конвейер (или любой другой процесс, используемый для публикации кода) защитит вас от непреднамеренного внедрения вредоносного стороннего кода.
Обратите внимание, что эти действия подразумевают под собой проверку кода сторонних разработчиков на известные уязвимости. Скорее всего, еще больше уязвимостей остаются неизвестными. Проверка на известные уязвимости является необходимым минимумом в создании безопасного программного обеспечения. Если разрабатывающееся программное обеспечение требует очень высокого уровня надежности, нужно тестировать и просматривать каждую строчку кода, от которого оно зависит. Лучшая практика – включать в приложение только необходимые сторонние компоненты, а не каждую новую крутую штуку, увиденную в интернете. Несмотря на сложности при продаже такого приложения (давайте признаем, что новые технологии – это интересно и весело), если вместо простого «нет» вы сможете объяснить существующие риски и предложить альтернативу или решение, то скорее всего добьетесь положительных результатов.
ПРЕДУПРЕЖДЕНИЕ О НАРУШЕНИИ КОНФИДЕНЦИАЛЬНОСТИ
Алиса хотела прикрепить свой зашифрованный личный онлайн-календарь к программе настольного календаря, чтобы видеть рабочий и личный календари в одном месте. Она прочитала страницу справки для программы настольного календаря, в которой говорилось, что нужно перевести параметр «Общий доступ к календарю» в режим «Публичный». Алиса была потрясена! Ее календарь зашифрован, потому что она хочет сохранить приватность личной информации. Она оставила жалобу, в которой объяснила, что данная страница должна предупреждать пользователей о возможных проблемах с конфиденциальностью при такой настройке. В результате Алиса получила обновленную программу настольного календаря.