Безопасность во Frontend или как пройти все круги Данте

fbc171139d075702dc9fccd01b2f5149

Здравствуйте. Сегодня обсудим безопасность, безопасную разработку и как получать документы, подтверждающие, что ваш продукт безопасен. Возникает резонный вопрос: зачем это вообще нужно? Ну, так как текущие реалии диктуют свои условия. И речь даже не о сложившейся геополитической ситуации в мире. А о том, что все больше и больше желающих получить то, что им не принадлежит. Будь то персональные данные, деньги, имущество, аккаунты игр (да-да, это тоже стоит денег), и в общем всё, что не прибито гвоздями.

Многие скажут, что на фронте всё безопасно, и что я сгущаю краски. Так как весь исполняемый код, по факту, находится у клиента в браузере. Отчасти соглашусь, но напомню, что фронт является дверью в бэк, а как мы все знаем, любая дверь, так или иначе, может быть открыта.

Следует помнить, что не всем подходит просто сказать: «У нас всё безопасно. Доверяйте нам!» Может, кому-то открою тайну, но бизнес так не работает. Бизнес хочет подтверждения безопасности. А это значит, получения сертификата соответствия в надлежащих органах, что само по себе отдельный вид девиации, но об этом позже.

Тема большая, неоднозначная. Постараюсь захватить как можно меньше от других частей систем (бек, тестирования, БД и т.д.). Но напоминаю, что безопасность — это комплексное мероприятие, в чем вы убедитесь позже, а сейчас по пунктам.

Для бизнеса это чуть ли не самая важная часть всего процесса, так как бумажка о том, что твой продукт сертифицирован, открывает множество новых возможностей. Даже если сертификатом в компании никто не будет пользоваться, важно то, что он есть (знаю такие случаи, некоторым банкам «Привет!»). Наличие оного позволяет участвовать в B2G и иметь преимущество в B2B.

Как вы думаете, как быстро можно получить сертификат?

Ответ: за месяц. И, как говорится: да, но нет. Формально, само получение сертификата недолгий процесс, но вот его подготовка… Там время может измеряться годами. Хотя, если вы уложитесь в несколько месяцев, уверяю, ощущать каждый из них вы будете, как целый год. На это есть ряд причин:


  • Требования в сертификации описаны весьма размыто. Например, вы должны проверить свой результат несколькими способами. Какими?
    У вас еще не подгорает? Минутку терпения.

    Нет-нет, шоу интуиция, расклад карт таро и гадание на кофейной гуще валидными вариантами не являются.


  • Требуется подготовить солидный пакет документов для подтверждения соответствия требованиям. Например, такие как:
    • Файзинг
    • Список открытых портов
    • Описание поверхности атаки
    • Описание внешних зависимостей
    • Описание модулей, которые вы используете
  • Самих сертификатов великое множество, а значит, требования разнятся.
  • Сдача всех документов происходит в бумажном варианте. Приготовьтесь распечатать объём примерно эквивалентный «Война и мир» 14 шрифтом…

Думаю, сертификация — это отдельный путь извращения, так как «приколов» с ней довольно таки много:

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


  • Отсутствие опыта — тенденция на то, чтобы сертифицировать Российское ПО, пошла после всем известных событий. Это значит, что случаи сертификации были, но это скорее исключение, нежели правило.
  • Сырая правовая база — законы, которые отвечают за данное направление, были приняты совсем недавно, а это значит, что редакции сырые. Отсутствуют общие практики.
  • Семь пятниц на неделе — как следствие вышеизложенного. Каждая лаборатория имеет свое мнение о том, что и как делать. При этом, как правило, вы для них являетесь подопытными крысами (лаборатории на вас просто учатся).

Так что с сертификацией это все, как говорится, дикий запад. Вам придется доказывать и объяснять лабораториям и не только им, что ваше ПО безопасно, так как пофиксить все уязвимости просто не представляется возможным, если вы используете сторонние зависимости. Или же доказывать, что данная уязвимость у вас нереализуема.

Многие сейчас пропагандируют, что требуется внедрять процесс безопасной разработки, и тогда сертификация покажется вам летней прогулкой. Давайте разберемся, так ли это.

Безопасная разработка программного обеспечения (БРПО) — это бизнес-процесс, предусматривающий внедрение практик и подходов обеспечения безопасности в ходе жизненного цикла разработки ПО (SSDLC), состоящий из комплекса организационных и технических мер.

БРПО по факту — это целый скоп ГОСТов и мер, которым вы должны соответствовать. А что это дает?


Плюсы

Повышение стабильности релизов программного продукта за счет улучшения транспарентности (прозрачности) разработки и выявления уязвимостей на самых ранних стадиях разработки. Снижение затрат сроков внедрения и повышение управляемости процесса внедрения автоматизированных информационных систем. Всё! На этом плюсы заканчиваются.


Минусы

Для реализации компании потребуется множество ресурсов, хотя по факту, это ничего не принесёт, кроме косвенных улучшений процесса. То есть, имея сертификаты по безопасной разработке, ваше выпускаемое ПО не получает нужный вам сертификат автоматически. Это значит, что вам все равно придется проходить процедуру его сертифицирования и значит, тратить на это ресурсы. Вы сейчас думаете, что наличие безопасной разработки ускорит получение сертификата? Нет.

Тогда зачем вот это всё нужно? Возможно, в будущем что-то придумают насчет каких-то преференций для тех, кто вложился в безопасную разработку, но сейчас их нет. Самое печальное в этой истории то, что это не разовые затраты, а черная дыра, которая будет сосать ресурсы, как не в себя.

Так как сегодня речь о безопасности, то пора поговорить о ней. Существует 2 направления безопасности во фронте:


Сетевая безопасность

Начать предлагаю с сетевой безопасности: фронт сам по себе бесполезен, так как у каждого клиента свой экземпляр приложения (сайта). Для нормальной работы фронту нужен обмен данными с беком, а так как канал обмена является самой уязвимой частью взаимодействия, то его и надо защищать. Тут сразу хочу подчеркнуть, что все нижеперечисленные методы защиты не реализуются без поддержки бэка. Главное помнить, что безопасность — это коллективная работа, отсюда часть советов будет находиться на стыке зон ответственности.

Для начала стоит использовать HTTPS протокол для вашего приложения (о том, как работает SSL/TLS, я рассказывать не буду: кому интересно, тот прочитает в интернете). Это позволит вам устанавливать защищенное соединение с беком, по-другому: шифровать ваш трафик.

Следующим логическим шагом будет использовать авторизацию для доступа к API и вообще каким-либо данным, имеющим ценность. Авторизация (аутентификация) должна быть защищена от brute force (переборки пароля). Это может быть captcha, если ее использование возможно, а лучше её использовать вместе с временной блокировкой аккаунта при N-ном количестве неправильных вводов пароля. Совместно с ними рекомендую использовать разные способы шифрования для передачи чувствительных данных. Вы спросите: «Зачем?» А затем, что трафик тоже можно считать. Вопрос «Как?» Например, используя наличие динамических параметров, которые выдаются сервером.

Для лучшего понимания представим, что вы отправляете пароль в незашифрованном виде, злоумышленник перехватывает его, и вот уже ваши данные доступа в его руках. Для того чтобы этого избежать, недостаточно просто зашифровать пароль, так как js исполняется на клиенте: пусть код и обфусцирован, его легко развернуть обратно в нормальный вид, вычленив алгоритм. Именно поэтому стоит использовать сложносоставное шифрование.

Сложносоставное шифрование — это когда выбор алгоритма шифрования и его настройки приходят с сервера, а фронт распоряжается только небольшой частью данного алгоритма или ключа. При этом каждый раз ключ разный. Таких алгоритмов великое множество, и перечислять их не хватит времени.

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

Зачастую дырки безопасности получаются просто из-за безалаберности разработчиков. Например, используя JWT, фронт сам создает cookie, точнее записывает их сам, и забывает, что HttpOnly защищают от скиптинга (XSS). Что приводит к тому, что злоумышленнику достаточно достать cookies c вашего устройства и все.

Еще одна глупость, которая часто встречается в сети, это оставление комментариев в готовом билде для прода, которые разработчик пишет для пояснения, а затем просто забывает о них. Или классика жанра: заметки в виде базового пароля, чтобы не забыть/запоминать. Поэтому, когда готовите к накату на прод, не забывайте настроить сборочную линию (CI/CD), чтобы при подготовке билда были удалены все комментарии.

Ещё одной часто встречающейся уязвимостью являются разного рода инъекции для получения сторонних данных, например, списка пользователей. Чтобы этого избежать, не забывайте использовать санитайзинг отправляемых данных на сервер. Справедливости ради стоит заметить, что фронт должен это делать не один, то есть сервер также должен осуществлять санитайзинг данных, которые к нему приходят, а не бездумно записывать их в базу. Еще раз повторю, что безопасность — это коллективная работа.

Представим: вы собрали свое приложение, использовали все вышеописанные методы и вроде бы всё хорошо, но не спешите расслабляться. Я пока не видел ни одного проекта, ну, наверное, за исключением совсем маленьких, в которых не было бы внешних зависимостей. А мы с вами уже знаем, чем больше сторонних компонентов (библиотек), тем больше потенциальных уязвимостей, которые может использовать злоумышленник. Возникает вопрос: ″Как их проверить? ″. Ведь есть не только зависимости, которые явно используются в вашем продукте, но и так называемые транзитивные зависимости.

Транзитивные зависимости — это те зависимости, которые используют ваши зависимости втихую. И тут возникает новый вопрос: ″Как же их всех отследить? ″. Здесь, к сожалению, не обойтись без тяжелой артиллерии в виде анализатора зависимостей.

Вот мы плавно подошли к инструментам, которые нам помогут обеспечить безопасность продукта уже на этапе разработки. Основными инструментами для достижения цели являются:


  • Артефактное хранилище, в котором будут храниться все ваши и не только артефакты;
  • Анализатор зависимостей, который будет анализировать не только явные зависимости, но и транзитивные;
  • Статический анализатор, который будет проверять не только качество кода, но и говорить, где вы налажали.

Съесть слона целиком и сразу не получится — просто подавитесь. Давайте попытаемся его расчленить и после проглотить.


Артефактное хранилище

Артефактное хранилище или регистри — это место, где будут храниться ваши приватные пакеты и не только.

Артефактное хранилище выполняет несколько функций: первая, как вы уже могли понять — это хранение приватных пакетов. Там будут храниться не только ваши пакеты, но и все зависимости. Снова резонный вопрос: «Зачем?». Дело в том, что, если вы каждый раз для сборки своего проекта будете ходить наружу, то в один прекрасный день злоумышленник может перехватить запрос на получение пакетов и подменить их.

Второй функцией хранилища является ускорение сборки, так как оно не будет загружено сторонними клиентами, и вы его контролируете. Тут я думаю, что не стоит собирать прод с npm i, а лучше использовать npm ci, так как i вам перегенерирует package-lock, а команда ci поставит именно те версии, которые там указаны, с поверкой хешей. Пример такого хранилища — Nexus.


Анализаторы зависимостей

Самыми известными анализаторами зависимости для js на текущий момент являются Nexus IQ, Dependency-Track, OWASP Dependency-Check. Все они по факту делают одно и то же. Основные отличия — это удобство использования, способы установки, какие базы уязвимостей используются и коэффициент ложных срабатываний.

Для выбора что использовать, можно прочесть прекрасную статью. Там наглядно изложены плюсы и минусы того или иного решения. Мы у себя используем Dependency-Track. Почему его? Просто он бесплатный, а еще его можно донастроить, как удобно, и добавить еще баз уязвимостей. Важно уточнить, что все перечисленное работает в основном с BOM файлами. И я прям чувствую ваше недоумение: ″Где же я на фронте возьму вам этот файл? ″. Вы такие не одни и для решения данной задачи был написан CycloneDX. И простой командой cyclonedx-npm --output-format XML --ignore-npm-errors --short-PURLs --output-file bom.xml вы получите заветный файл, а далее сможете его загрузить в одну из систем.


Опыт использования Dependency-Track.

Наверное, будет сложно передать ту боль, которую я испытывал в начале знакомства с данным ПО. Сказать, что я был в гневе — это ничего не сказать!

Как сказал мой коллега Артем (имя изменено), что он был бы хорошим отчимом и еще лучшим пати мейкером тем людям, которые создали сие чудо инженерной мысли, и особенный респект UI аналитикам, или кто там проектировал это. Для того чтобы прочувствовать эту боль, стоит учесть, что документация не то чтобы сильно подробная. Разбираясь с настройками, иногда вообще не понятно, что и зачем нужно. Случается так, что написано одно, ты это применяешь, но всё остаётся, как было. Дальше только эмпирический метод. Например, ещё на окне создания проекта складывается ощущение, что чтобы ты не выбрал из типов проекта, ничего не меняется, во всяком случае для JS.

Вишенкой служит целый ворох ложных срабатываний. Как я понял, Dependency-Track ищет название библиотеки, а затем сравнивает его со своей базой. Если ваша приватная либа имеет идентичное название хотя бы одной либе с проблемами, вы получите ложное срабатывание. Также были замечены случаи: если название одной библиотеки более чем на 70–80% схоже с названием другой библиотеки, то может прилететь замечание не от той либы. Как оказалось впоследствии, это всё, или хотя бы частично, фиксится донастройкой. Но из коробки, Боже упаси использовать! Ввиду ограничений на использование платного ПО, в связи с запретами — это пока лучшее, что мы имеем.


Статический анализатор

Статический анализатор кода — это инструмент, который позволяет программистам автоматически анализировать и проверять качество и безопасность их программного кода. Данных программ тоже великое множество. У себя в компании мы используем Российскую разработку appScreener — не самое лучшее, но и не самое плохое. Из плюсов для JS:


  • 10+ методов статического анализа;
  • Сложные правила поиска;
  • Быстрый запуск сканирования;
  • Современный графический интерфейс — спасибо, что вообще есть;
  • On-premise и SaaS;
  • Сертификат ФСТЭК России.

Мы залили в него наш проект, и на выходе получили довольно подробные рекомендации по исправлениям. Правда есть неловкий момент: в js он new Date () оценивает как уязвимость нулевого дня. В общем, придется поучить его уму-разуму, но скрашивает множественные действия. То есть при составлении отчета об уязвимостях мы получаем группировку по типу, а также ранжирование по критичности.

Стоит один раз указать, где он облажался, потом, вроде как, раздупляется.

Учитывая всё вышеизложенное, в итоге вы получаете почти безопасное приложение с фронта, если устраните всё то, что вам насоветуют системы, но ключевое слово «почти».

Почему почти? Да потому, как нет предела совершенству. Каждый день изобретаются все новые и новые способы и ухищрения для получения доступа к вашим данным. Также помните, что вы один в поле не воин (фронт). И все, что вы делаете, это вы делаете с беком. Также будьте очень внимательны к тому, что и как вы делаете. Чем меньше зависимостей, тем меньше потенциальных дырок. А так, хочу вам пожелать терпения… Оно ох как вам понадобится.

Хочу сказать огромное спасибо моим коллегам. Артему (имя изменено) за разделение чувств к инженерным изыскам. За фразы, которые имеют такое хитросплетение ругательств, что я просто не мог их воспроизвести, даже дословно, не говоря о том, чтобы как-то адаптировать их для статьи. Так же благодарю Александра С. (имя настоящее), спасибо тебе огромное, что слушал мою брань на весь процесс сертификации (тот, кто его разработал, земля тебе стекловатой). А также за то, что помогал с настройками всего и вся. Как говорится, ребята, бьюсь челом об пол!!!

© Habrahabr.ru