Race condition в веб-приложениях
Представьте ситуацию. Вася хочет перевести $100, которые есть у него на счету, Пете. Он переходит на вкладку переводов, вбивает Петин ник и цифру 100. Затем нажимает на кнопку перевода. Данные отправляются на сервер. Что нужно сделать, чтобы всё сработало правильно?
Вроде всё просто:
1. Убедиться, что у Васи достаточно денег на счету.
2. Вычесть из баланса Васи сумму, которую необходимо перевести.
3. Добавить к балансу Пети эту сумму.
4. Вывести Васе сообщение, что он молодец.
Всё бы ничего, если бы всё происходило в порядке очереди. Но сайт может обслуживать одновременно множество пользователей, а это происходит не в одном потоке. C появлением многопоточности у программ появилась интересная архитектурная уязвимость — состояние гонки (или race condition).
А теперь представим, что наш алгоритм срабатывает одновременно 3 раза (или Вася что-то перепутал, или злоумышленники задумали что-то нехорошее).
У Васи всё так же $100 на балансе, но теперь он обращается к серверу тремя потоками одновременно (с минимальным количеством времени между запросами). И все три потока проверяют, достаточно ли баланса у Васи для перевода. В тот момент времени, когда алгоритм проверяет баланс, он всё еще равен $100. Как только проверка пройдена, из текущего баланса 3 раза вычитается $100, и добавляется Пете.
Что мы имеем? У Васи на счету минусовой баланс, а у Пети + $300, хотя должно быть + $100. Это и есть типичный пример эксплуатации уязвимости состояния гонки.
Как избавить своё приложение от такой уязвимости? В этой статье рассматривается несколько вариантов: https://bo0om.ru/race-condition-ru
#бэкенд #http #многопоточность
Представьте ситуацию. Вася хочет перевести $100, которые есть у него на счету, Пете. Он переходит на вкладку переводов, вбивает Петин ник и цифру 100. Затем нажимает на кнопку перевода. Данные отправляются на сервер. Что нужно сделать, чтобы всё сработало правильно?
Вроде всё просто:
1. Убедиться, что у Васи достаточно денег на счету.
2. Вычесть из баланса Васи сумму, которую необходимо перевести.
3. Добавить к балансу Пети эту сумму.
4. Вывести Васе сообщение, что он молодец.
Всё бы ничего, если бы всё происходило в порядке очереди. Но сайт может обслуживать одновременно множество пользователей, а это происходит не в одном потоке. C появлением многопоточности у программ появилась интересная архитектурная уязвимость — состояние гонки (или race condition).
А теперь представим, что наш алгоритм срабатывает одновременно 3 раза (или Вася что-то перепутал, или злоумышленники задумали что-то нехорошее).
У Васи всё так же $100 на балансе, но теперь он обращается к серверу тремя потоками одновременно (с минимальным количеством времени между запросами). И все три потока проверяют, достаточно ли баланса у Васи для перевода. В тот момент времени, когда алгоритм проверяет баланс, он всё еще равен $100. Как только проверка пройдена, из текущего баланса 3 раза вычитается $100, и добавляется Пете.
Что мы имеем? У Васи на счету минусовой баланс, а у Пети + $300, хотя должно быть + $100. Это и есть типичный пример эксплуатации уязвимости состояния гонки.
Как избавить своё приложение от такой уязвимости? В этой статье рассматривается несколько вариантов: https://bo0om.ru/race-condition-ru
#бэкенд #http #многопоточность