Книга: Безопасность веб-приложений. Исчерпывающий гид для начинающих разработчиков
Назад: Подделка запросов со стороны сервера (SSRF)
Дальше: Тестирование кода

Состояние гонки

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

Представьте, что Алиса хочет отредактировать файл на одном из общих рабочих дисков. Она открывает его, и программа обработки текстов накладывает на него временную блокировку. Если позже Боб захочет открыть этот же документ, то программа позволит ему увидеть его в формате «только для чтения», чтобы он не перезаписал изменения коллеги.

А представьте, что будет, если программа не заблокирует файл? Такие ситуации возникают чаще, чем вы думаете.

Предположим, что по дороге домой с работы вы захотели зайти в продуктовый магазин, чтобы купить продукты на ужин. Перед выходом вы проверили свой счет и увидели на нем $60. Пока вы выбирали продукты, ваш супруг либо супруга произвел(а) несколько оплат, оставив на счету всего $10. К моменту расчета на кассе счет обновился и составляет лишь $10, из-за чего оплата по карте не проходит. Хотя данный пример, безусловно, не идеален, он описывает суть проблемы.

Теперь представьте, что кто-то намеренно пытается создать состояние гонки. Он использует карту для онлайн-покупок, пополняет ее, а в момент нажатия кнопки «Купить» одновременно пытается перевести деньги на другой счет. В идеале банковское программное обеспечение должно наложить блокировку на счет до завершения транзакции № 1, а затем попытаться провести транзакцию № 2. Порядок транзакций определяется в зависимости от того, какой запрос был получен первым.

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

• конкуренция за ресурсы (редактирование документа);

• обновление материальных ценностей (банковский баланс);

• все ситуации, где время выполнения одного действия зависит от другого условия.

Самым простым способом смягчения данной атаки является блокировка любой записи, находящейся в процессе изменения, до завершения действия. Если одна операция зависит от другой, перед началом следующей операции убедитесь, что предыдущая уже завершена. Необходимо заложить в структуру приложения программирование зависимостей. Незавершенную транзакцию следует откатить, в случае целесообразности – выдать ошибку и закрыть (а не допускать открытого или неизвестного состояния приложения).

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

Заключительные комментарии

Не нужно заучивать OWASP Топ-10 наизусть, если только вы не создаете презентацию на данную тему или не идете на неоправданно напряженное собеседование. А вот что делать нужно, так это применять при создании программного обеспечения защитные меры, представленные в этой книге.

Упражнения

• Кто-то из вашей проектной команды хочет принять сериализованные объекты из ненадежного источника. Вы знаете, что это плохая идея. Как можно эффективно объяснить риск коллеге? Запишите ответ. Объяснение должно быть убедительным и понятным.

• OWASP Топ-10 является стандартом обеспечения безопасности: да или нет?

• Назовите три пункта из OWASP Топ-10, которые были упомянуты в книге до главы 5.

• Применима ли уязвимость XXE к JSON? Применима ли она к YAML? Если да, почему? Если нет, то почему?

• Назовите пример ситуации (не обязательно связанной с компьютером), когда возникает состояние гонки.

• Почему мы откатываем незавершенные транзакции? Почему это важно? Приведите пример негативных последствий отказа от отката.

Часть II

Как написать безупречный код

Глава 6. Тестирование и развертывание

Глава 7. Программа безопасности приложений

Глава 8. Обеспечение безопасности современных систем и приложений

Глава 6

Тестирование и развертывание

Эта глава посвящена тестированию и развертыванию приложения и систем, от которых оно зависит: API, инфраструктуры, базы данных и т. д.

В данной книге тестированием называется проверка качества, надежности и безопасности программного обеспечения. Другими словами, это проверка того, что программное обеспечение выполняет только определенные клиентом функции и отвечает установленным требованиям проекта. Цель тестирования заключается также в подтверждении того, что конфиденциальность, целостность и доступность (CIA) системы и ее данных защищены должным образом.

Под развертыванием в книге понимаются «действия, предпринимаемые для публикации приложения». Это может быть нажатие правой кнопки мыши на приложение и выбор «Опубликовать», ручное копирование и вставка кода на сервер, составление формальной документации по задаче для проектной группы или создание целой автоматизированной системы непрерывной интеграции и непрерывной поставки (CI/CD).

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

Назад: Подделка запросов со стороны сервера (SSRF)
Дальше: Тестирование кода