| Слушать на Google Podcasts | Слушать на Mave | Слушать на Яндекс Музыке |
Роман Душков, Security Vision
Современная разработка стремится к упрощению кода, увеличению его предсказуемости и эффективности. Рассмотрим, как превратить непрерывный процесс DevOps в безопасный и заботящийся о пользователях и их безопасности DevSecOps.
Один из способов – самозащита приложений во время их запуска и работы (Runtime application self-protection, RASP). Она анализирует поведение приложений и определяет, с одной стороны, их возможности, с другой – зоны их работы, поскольку приложения могут выйти за границы ожидаемого поведения, получить доступ к лишней информации и просто оказаться небезопасными для конечных пользователей.
Ещё про один способ заключается в том, что, в отличие от анализа уже работающего приложения, иногда исследуется код, написанный разработчиками. Средства анализа исходного кода приложений (Application Security Testing, AST) мы разберём в этой статье на примере работы статических анализаторов (Static AST, SAST). SAST-анализаторы используются для исследования кода на наличие в нем уязвимых команд, нелогичных взаимосвязей и информации, которой в хорошем коде быть не должно.
Рис. 1 – Механизмы статического анализа кода
Процесс работы SAST-систем можно сравнить с конвейером, на который поступает текст, написанный разработчиками, а на выходе предоставляется отчет со списком ошибок. Такой конвейер будет работать по-разному для текстов, написанных на разных языках, но обычно вендоры предлагают средства анализа для всех популярных языков программирования.
Чтобы конвейер работал эффективно, его нужно не только создать, но и периодически настраивать, улучшать и ускорять. Для этого вендоры постоянно пополняют свою базу знаний, добавляя на к отчёту с ошибками еще и способы их устранения. В качестве такой базы знаний используются справочники, например, OWASP, GitHub и CVSS.
Итак, два важных фактора для эффективной работы SAST - понимание языка, на котором написано приложение, и знания о том, как недочеты могут быть устранены. Теперь разберем по этапам, как система обрабатывает текст. Представим, что вместо приложения мы пишем статью – после написания основного текста его передают редакторам, которые 1) исправляют ошибки 2) делают текст более удобочитаемым 3) находят ключевые слова для быстрого поиска и отображения статьи в поисковых системах. Исходный код приложения также анализируется по-разному.
Сначала прибегают к синтаксическому анализу. Синтаксис различается не только в русском, английском, немецком и других человеческих языках, но и для Python, GO и C++ и других языках программирования. Однако в определённой степени все языки похожи: так же, как в человеческих языках можно выделить подлежащее, сказуемое и другие части речи, так и в языках программирования можно выделить операторы, команды и комментарии. Синтаксический анализ позволяет обнаружить отдельные фрагменты и области, как в теореме о 1000 знаков. Работа синтаксического анализатора подобна работе систем Asset Management, когда все IT-активы компании раскладываются по полочкам для построения карты сети и быстрого поиска, например, серверов на стадии ремонта. Или, если вернуться к тексту этой статьи – проверке синтаксиса в Microsoft Word, в результате которой проставляются нужные знаки препинания, сам текст разбивается на абзацы и комфортные для чтения фразы, появляется структура, которую удобнее воспринимать алгоритмам SAST.
После включается семантический анализатор, который ищет соотношение формы сообщения и его смыслового содержания. Так, например, ноль в программировании можно представить в виде целого числа (0), числа с плавающей запятой (0,000000001) или булевой переменной (False). С каждой переменной можно взаимодействовать по-разному: например, к целому числу можно прибавить другое. А с переменной True/False работать по правилам математической логики. При анализе исходного кода на данном этапе система определяет возможности команд и операторов, которые могут быть оптимизированы. С точки зрения анализатора можно не знать точных значений переменных, но видеть, что данные поступили из внешнего источника. Такие данные могут быть скомпрометированы, значит, нужно сообщить разработчику, как избежать, например, SQL-инъекций и переполнения буфера.
Ещё один способ проанализировать уязвимости в коде – изучить транспорты, по которым передается информация. В жизни каждый из вас скорее всего сталкивался с курьерскими службами (доставкой цветов, продуктов из супермаркета и ресторана, хранением ключей в сейфах при использовании Airbnb и т.д.). Каждый из способов доставки имеет свои преимущества: скорость, мобильность курьера, размеры грузовика для транспортировки мебели, надежность и безопасность. При создании приложений также используются разные транспортные протоколы, часть из которых нацелена на обработку файла, поиск данных в СУБД, API-приложений и др.
Важно определить возможные риски применения разных протоколов - часть этой работы берет на себя система класса SAST, или хранилище секретов в коде. Последнее хранилище похоже на мини-сейфы для ключей в гостинице или хранилище паролей в браузере: вместо использования логинов и паролей к системам можно применять переменные, которые будут надёжно храниться отдельно и вызываться уже в процессе работы приложения. Так злоумышленник, получивший исходный код, не сможет найти данные для авторизации в важной для вас системе, а значит, не сможет её так просто атаковать.
Поскольку мы занимаемся не только оркестрацией различных средства зашиты информации, но и автоматизацией рутины и сложных процессов, в заключение описания SAST-систем мы хотим подсветить критичность самих процедур. С одной стороны, важно вовремя заметить уязвимое место, но еще более важно – быстро и качественно его прикрыть. Если уязвимое ПО уже используется, а саму уязвимость ещё не придумали, как устранить, можно либо принять риски, либо обеспечить доступность данных при введении новых политик безопасности. Существуют разные комьюнити разработчиков, которые помогают описывать проблемы и тестировать свои наработки. Внутри компаний, где применяется уже готовое программное обеспечение, часто нет возможности увидеть и исправить его исходный код, поэтому возникновение уязвимостей становится неизбежным. При организации процессов важно работать эффективно с обеих сторон: разработка должна быть безопасной, а устранение существующих проблем - простым и понятным процессом.
Используя описанные выше технологии, можно провести анализ кода до его компиляции, т.е. до выпуска новой версии продукта, поэтому разработчики могут добавить SAST для обеспечения безопасности в свои процессы ещё на этапе разработки, совместно с общепринятыми методами CI/CD. Сам по себе продукт не исправит слабые и уязвимые участки кода, но подсветит возможные риски. В дальнейшем безопасность можно усилить специальными хранилищами секретов, сканерами уязвимостей или анализаторами кода, которые работают динамически.