Приложения живут в инфраструктуре: физические серверы, виртуальные машины (ВМ), контейнеры. Даже бессерверные приложения недолго работают в контейнере, прежде чем самоуничтожиться. В обязанности специалиста по безопасности приложений или разработчика обычно не входит исправление таких систем, но если приложение скомпрометировано из-за небезопасной инфраструктуры, это станет и его проблемой в том числе. В данной книге мы не станем рекомендовать вам создавать собственную инфраструктуру или проводить оценку безопасности сети, но выполнение базовых проверок может быть весьма полезным.
Все три типа инфраструктуры – физические серверы, виртуальные машины и контейнеры – работают под управлением операционных систем, которые могут быть просканированы на предмет отсутствия необходимых патчей, плохой конфигурации и других аномалий, требующих внимания разработчика (или команды эксплуатации).
При наличии автоматизированного конвейера развертывания, выпускающего инфраструктуру, стоит добавить соответствующее программное обеспечение для его сканирования. Сотрудники эксплуатационного отдела должны своевременно получать и использовать результаты проверки.
Например, если для размещения приложения применяются контейнеры, можно воспользоваться руководством по стандартам Центра интернет-безопасности (англ. Center for Internet Security, CIS) для усиления их защиты. Можно использовать несколько различных видов инструментов для сканирования контейнера на предмет соответствия его конфигурации стандарту CIS (github.com/dev-sec/cis-docker-benchmark).
При ручном запуске программного обеспечения можно узнать у своей команды эксплуатации и службы безопасности, что им нужно для обеспечения безопасности платформы. Они могут ответить «ничего», а могут и поделиться отличными идеями. В ваших интересах сделать все от вас зависящее для повышения уровня безопасности в рамках инфраструктуры.
Базы данных представляют собой инфраструктуру и управляют вашими данными. Как и любой другой сервер, они должны быть защищены, однако нужно также обеспечить безопасность самих данных.
Необходимо регулярно сканировать инфраструктуру с помощью сканера оценки уязвимостей.
Следует убедиться, что:
• каждая учетная запись имеет доступ только к тем областям и базам данных, к которым она должна иметь доступ;
• нельзя подключиться ни к одной части сервера без учетной записи;
• все порты закрыты, кроме необходимых для работы;
• сервер подключен к сети через модель нулевого доверия (все закрыто либо заблокировано, кроме приложений, которые он обслуживает);
• на сервере нет другого программного обеспечения, кроме операционной системы сервера базы данных;
• все данные засекречены и маркированы, вплоть до низового уровня (секретно, совершенно секретно или несекретно);
• эксплуатационные данные не используются ни в каких других средах. Данные клиента ни в коем случае не должны использоваться для тестирования или разработки;
• доступ контролируется и проверяется на предмет раскрытия конфиденциальных данных и ненадлежащего доступа (например, сотрудники не ищут в базах данных сведения о людях из своей личной жизни);
• для каждого приложения используются уникальные сервисные учетные записи, и ни одна из них не наделена правами владельца базы данных или любыми другими чрезмерными разрешениями;
• когда это возможно, используется подсервисная учетная запись, соответствующая типу операции: одна учетная запись предназначена для операций READ, а другая – для операций CREATE/UPDATE/DELETE с целью предотвращения изменения данных в случае компрометации пользователя с правами READ;
• регулярно создаются резервные копии и практикуется откат;
• данные шифруются в пути (на пути к БД и обратно) и в состоянии покоя (вся БД шифруется как единое целое);
• поля конфиденциальных данных зашифрованы в базе данных (второй уровень шифрования);
• все возможные средства контроля и функции, связанные с обеспечением безопасности, включены в соответствии с руководством по усилению безопасности, если нет документально подтвержденной причины не делать этого;
• сообщения об ошибках не содержат слишком много информации;
• в настройках разрешения DNS установлено значение «только для внутреннего пользования»;
• все остальное, что можно придумать. Этот список не является исчерпывающим.
Также можно обратиться к руководству от CIS, чтобы определить, какие меры по усилению безопасности можно применить к базе данных в дополнение к передовым практикам обеспечения безопасности, предоставленным поставщиком базы данных.
API используются веб-приложениями для взаимодействия с веб-службами, ни одна из которых не имеет графического интерфейса пользователя (англ. graphical user interface, GUI). Они требуют такого же тестирования, как и обычные веб-приложения, за исключением тех частей, которые связаны с GUI. Тем не менее проверка API и веб-служб достаточно сложна по нескольким причинам.
Во-первых, как правило, API скрыты. Они не имеют графического интерфейса и поэтому видны только при вызове их из приложения (увидеть вызов можно лишь с помощью веб-прокси). Необходимо попытаться вручную перечислить API (найти их все), разобраться во всех функциях, и только затем можно приступать к тестированию – это большой объем работы. В идеале заказчик предоставляет как можно больше подробностей о системе (например, файл с определением API), однако все равно тестировщику приходится перечислять все самому, поскольку зачастую API больше, чем люди думают.
Во-вторых, на момент написания этой книги на рынке представлено мало автоматизированных инструментов тестирования безопасности, ориентированных на API, и мне еще не попадался тот, который работал бы так же хорошо, как современные сканеры веб-приложений (DAST). Использование инструмента DAST для поиска уязвимостей в веб-приложении не требует длительного обучения, API же обычно тестируется вручную посредством веб-прокси или инструмента, который может сам выполнять вызовы API. На данный момент существуют новые инструменты, которые ищут файлы определения API и тем самым облегчают тестирование, но полностью автоматизированного решения для поиска уязвимостей в этой области нет. Таким образом, тестирование API должен проводить человек с соответствующей подготовкой, что увеличивает стоимость выполнения данной задачи.
Для тестирования API следует составить запрос к нему для вызова какой-либо функции. Если вы знаете, как приложение выполняет этот вызов, просто скопируйте его. Если это API, на который вы наткнулись при выполнении перечисления, может потребоваться какое-то время, чтобы правильно оформить первый запрос. Сформировать запросы поможет файл определения. Как только у вас будет правильный запрос, начните отправлять «ненадлежащие» запросы, измененные, запросы с атаками и т. д. Пройдитесь по каждому API и всем функциям внутри него. Проверьте работоспособность функций, вызвав каждую из них с помощью различных HTTP-методов (GET, POST, PUT, DELETE и т. д.). Протестируйте пределы (насколько большим или маленьким может быть значение, тип, количество вызовов и т. д.). Попробуйте добавить «плохие» вводные данные и попытки атаки: одинарные кавычки, теги <script>
и т. д. Сделайте все то же самое, что сделали бы с полем ввода веб-приложения, которое может вызывать API в бэкенде. Это ваш шанс обратиться непосредственно к API без вмешательства веб-приложения.
Как и любое ручное тестирование, проверка API таит в себе больше нюансов, чем мы упомянули, но со временем вы отточите этот навык. Запомните главное: API необходимо тестировать так же тщательно, как и любое веб-приложение, поскольку это не менее ценная мишень для атак.