0204411e98
Тот же класс, что нашли во втором проверяющем на СМС: чтение денег идёт вне куска с контекстом клиента. Проверил свой модуль целиком по этому признаку. Дыра одна, в самом больном месте. Джоб проверки модерации кампании перечисляет кампании через обходное соединение, но возврат заморозки зовёт кошелёк на обычном соединении и без контекста. Защита по клиентам на таблицах рекламы устроена строго: без контекста сравнение с пустотой, и база отдаёт ноль строк. Чем кончалось бы на бою: Яндекс отклонил весь набор объявлений - кампания помечена отклонённой - возврат заморозки видит "кошелька нет", честно выходит - деньги клиента остаются замороженными навсегда. Ни ошибки, ни строки в журнале, свободный остаток занижен, новую кампанию запустить не на что. Живой замер на опытной базе, откатанный сразу: суперюзером, как ходят тесты - 1 боевой ролью без контекста, как читает джоб - 0 боевой ролью с контекстом - 1 Тесты ходят суперюзером, который защиту обходит, и увидеть это физически не могут. Починка в самом кошельке, а не у вызывающего. Тенант приходит в кошелёк явным доводом, значит и контекст - забота кошелька, а не каждого, кто его позовёт. Так закрыт весь класс сразу, а не один случай. Сторож гоняет деньги ПОД БОЕВОЙ РОЛЬЮ и без контекста. Написан до починки, падал двумя разными способами: возврат молча ничего не делал, заморозка бросала "кошелька нет". Опасен именно молчаливый. Обход остальных фоновых путей: перечисление кампаний, сторож зависших заданий, сборка аудитории, постановка задания разведки, запись в ленту - у всех защита на месте. Список получателей уведомления читается из таблицы, у которой политика мягкая: без контекста она открыта, ноль строк не даёт. Реклама 395 из 395 при 1251 проверке, было 393. Админка и кошелёк 25 из 25. На боевой не выкатывалось, никуда не отправлялось. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>