Найти в Дзене

14 миллионов из-за одной кнопки Расследование тихой уязвимости сервиса доставки

На первый взгляд он ничем не выделялся. Обычный курьер из Екатеринбурга, двадцать девять лет, тихий, без амбиций, без резюме, которое хочется читать. Не конфликтовал, не опаздывал, не спорил с поддержкой. Работал в основном ночью, часто брал смены подряд, редко уходил в выходные. В системе он выглядел как удобный исполнитель — незаметный и надёжный. Именно поэтому на него не обращали внимания. В логистических компаниях курьеры редко становятся объектом пристального контроля, если не создают проблем. Основной фокус всегда направлен на маршруты, сроки, процент выполненных заказов. Отдельный человек растворяется в статистике. Особенно если он работает тогда, когда большинство менеджеров и контролёров уже ушли домой. Он это понял довольно быстро. Первые месяцы работы ничем не отличались от сотен других. Забрать заказ, отвезти, подтвердить доставку в приложении. Иногда клиенты отменяли заказы в последний момент. Иногда магазин уже закрывался. Иногда поддержка отвечала с задержкой. Всё это

На первый взгляд он ничем не выделялся. Обычный курьер из Екатеринбурга, двадцать девять лет, тихий, без амбиций, без резюме, которое хочется читать. Не конфликтовал, не опаздывал, не спорил с поддержкой. Работал в основном ночью, часто брал смены подряд, редко уходил в выходные. В системе он выглядел как удобный исполнитель — незаметный и надёжный.

Именно поэтому на него не обращали внимания.

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

Он это понял довольно быстро.

Первые месяцы работы ничем не отличались от сотен других. Забрать заказ, отвезти, подтвердить доставку в приложении. Иногда клиенты отменяли заказы в последний момент. Иногда магазин уже закрывался. Иногда поддержка отвечала с задержкой. Всё это считалось обычными издержками сервиса.

Ошибка проявилась случайно.

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

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

На следующий день он снова связался с поддержкой и сообщил о ситуации. Ответ пришёл спустя несколько часов. Ему предложили вернуть товар в магазин при первой возможности. Никаких санкций не последовало. Заказ в системе так и остался «доставленным».

Тогда это выглядело как разовый сбой.

Через пару недель ситуация повторилась. И снова — ночная смена, отмена после получения, задержка ответа поддержки, магазин закрыт. И снова — статус «доставлено».

Он начал проверять внимательнее.

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

Для компании это выглядело как нормальная доставка. Деньги списывались. Комиссия начислялась. Никакого «висяка» не возникало.

Товар оставался у курьера.

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

Он начал наблюдать.

Ошибка возникала не всегда, но достаточно часто, чтобы быть воспроизводимой. Чаще всего — ночью. Поддержка отвечала медленнее. Магазины закрывались раньше. Контроль был слабее. Система жила своей автоматической жизнью.

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

Через несколько месяцев он стал сознательно брать ночные смены. Выбирал маршруты с крупными заказами. Электроника, бытовая техника, инструменты. Те позиции, которые легче перепродать и сложнее отследить.

Он не брал всё подряд. Только заказы, где риск отмены был выше: длительная доставка, нестабильный клиент, задержка на стороне магазина. Он ждал.

Иногда за ночь отменялось два заказа. Иногда три. В удачные смены — четыре. Каждый раз сценарий повторялся. Отмена. Молчание поддержки. Статус «доставлено». Начисление оплаты.

Компания не видела расхождений. В отчётах всё сходилось. Клиент отменил заказ — деньги вернулись. Курьер доставил — деньги получил. Товар нигде не «висел».

Так продолжалось месяцами.

Он не торопился. Не пытался резко увеличить объёмы. Понимал, что резкие скачки привлекают внимание. Работал ровно, как всегда. Тот же рейтинг. Те же смены. Те же показатели.

Разница была в том, что часть заказов до клиента никогда не доходила.

Постепенно у него появился круг перекупщиков. Люди, которые не задавали лишних вопросов. Электроника уходила быстро. Бытовая техника — чуть медленнее. Инструменты — почти сразу. Цены были ниже рыночных, но не подозрительно низкими.

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

Самое важное заключалось в том, что схема не требовала расширения. Он не вовлекал других курьеров. Не делился деталями. Работал один.

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

Баг исправили случайно.

Во время планового обновления приложения разработчики изменили механизм синхронизации статусов. Старые данные подтянулись. Несоответствия всплыли задним числом.

Система обнаружила невозможное. Один курьер «доставил» больше товаров, чем целый отдел за тот же период.

К тому моменту он уже уволился.

За неделю до обновления он подал заявление. Закрыл аккаунты. Сменил номер телефона. По слухам, уехал из России и перебрался в Грузию. Формально — обычное увольнение по собственному желанию.

Неформально — самый успешный курьер в городе.

Он не взламывал систему. Он просто заметил ошибку, которую никто не видел два года.

А такие ошибки, если их однажды увидеть, уже невозможно развидеть.

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

Он не просто выделялся. Он ломал статистику.

За два года этот курьер числился как человек, который доставил больше дорогостоящих заказов, чем целая группа сотрудников, работающих днём, в пиковые часы и под постоянным контролем. При этом жалоб на него не было. Возвратов — тоже. Рейтинг оставался стабильным. Формально он выглядел как идеальный исполнитель.

После этого начался внутренний аудит.

Проверку начали с заказов, которые система пометила как аномальные. Это были доставки, отменённые клиентами, но закрытые как выполненные. Таких записей оказалось значительно больше, чем ожидали. Сначала десятки. Потом сотни.

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

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

Разработчики подтвердили: в старой версии приложения действительно существовало «окно», в котором отмена заказа не всегда корректно обновляла статус. Это окно считалось маловероятным. Оно возникало при сочетании нескольких условий и потому долго не попадало в фокус тестирования.

Формально это был баг. Но баг, который жил внутри логики продукта и не ломал систему напрямую.

Когда начали поднимать логи, стало ясно, что курьер попадал в это окно регулярно. Слишком регулярно, чтобы это было случайностью. Он не создавал условия искусственно, но умел их распознавать. Он знал, какие заказы «падают» в зону риска. Знал, в какие часы поддержка отвечает медленнее. Знал, какие магазины закрываются раньше.

Он не вмешивался в код. Он просто действовал так, чтобы система сама принимала нужное ему решение.

Следующий этап проверки был самым сложным. Нужно было понять, где находится товар. Формально он числился доставленным клиенту. Клиент от заказа отказался и деньги получил обратно. Магазин не получал возврат. Товар выпадал из цепочки.

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

Тогда стали проверять движение денег.

По отчётам курьер получал стандартную оплату за доставку. Никаких аномальных начислений. Основная прибыль была за пределами платформы. Перепродажа. Частные сделки. Наличные или переводы через сторонние сервисы.

Юридически доказать хищение оказалось сложно. Курьер не подписывал акт приёма-передачи клиенту. Он действовал в рамках инструкций: при отмене — связаться с поддержкой. Он это делал. Возврат в магазин был невозможен из-за времени. Дальше система принимала решение сама.

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

К моменту, когда служба безопасности попыталась с ним связаться, его аккаунт уже был закрыт. Он уволился официально, без конфликтов. Документы были в порядке. Контакты — недоступны.

Внутренние обсуждения длились несколько месяцев. Подавать заявление означало публично признать уязвимость сервиса. Не подавать — списать миллионы как потери от ошибки. В итоге ограничились внутренними мерами.

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

Но деньги не вернулись. Товар — тоже.

Внутри компании этот кейс ещё долго использовали как пример «тихого риска». Не взлом. Не мошенничество в классическом виде. А человек, который понял систему лучше, чем она понимала себя.

Он не оставил после себя громкого дела. Только цифры, которые однажды перестали сходиться. И напоминание о том, что самые опасные ошибки — те, которые выглядят как нормальная работа.