Услуги Портфолио Контакты БлогНовости +7 (800) 511‑32‑27 Обсудить проект
Безопасность

Google закрыл RCE в DevSite: ключ подписи Flask-сессий лежал прямо в cookie

13 октября 2026·5 мин чтения
Google DevSitePython pickle
Треснувшая светящаяся сфера над серверной стойкой, из которой высыпаются фрагменты сериализованных данных

7 октября 2026 года Google закрыл критическую уязвимость в DevSite — общей платформе документации, на которой работают developers.google.com, firebase.google.com, developer.android.com и source.android.com. OAuth client_secret одновременно лежал в Flask-cookie и служил ключом подписи сессий, поэтому любой посетитель мог подделать сессию с pickle-нагрузкой и выполнить код на сервере без входа.

Ошибку нашёл инженер Simon Köck и получил за неё $90 000 по программе Google Vulnerability Reward Program. Сама находка — не экзотика уровня Google, а сочетание трёх типовых решений, которые встречаются в обычных Python-проектах: секрет в клиентском хранилище, переиспользование одного ключа для разных задач и десериализация недоверенных данных. Именно такие связки ищет аудит кода приложения, и именно их не видит сканер зависимостей.

Ниже — как была устроена цепочка, почему исправление заняло два месяца и что проверить в своих Flask- и Django-сервисах. Общие принципы защиты сессий мы разбирали в материале о безопасной аутентификации в веб-приложениях.

Как работала цепочка от cookie до выполнения кода

По разбору исследователя, атака складывалась из пяти шагов, и ни один из них не требовал учётной записи Google:

  • запрос к открытому эндпоинту авторизации OAuth на developers.google.com возвращал Flask-cookie сессии — заметно больше, чем нужно для CSRF-токена и адреса возврата;
  • после base64-декодирования и распаковки zlib внутри обнаруживались сериализованный через pickle объект OAuth-потока и пара client_id / client_secret в открытом виде;
  • тот же client_secret использовался как Flask SECRET_KEY: подпись, пересчитанная офлайн этим значением, побайтно совпала с подписью на cookie;
  • зная ключ, можно было записать в сессию любые данные и получить подпись, которую сервер принимал как свою;
  • OAuth-callback вызывал pickle.loads() для объекта из сессии, и подменённая нагрузка исполнялась при десериализации.

Выполнение кода исследователь подтвердил безопасно — нагрузкой с time.sleep(): задержка ответа сервера совпадала с заданной.

Какие сайты Google были затронуты

DevSite — общая инфраструктура, поэтому один ключ подписывал сессии сразу на нескольких доменах. В отчёте перечислены developers.google.com, firebase.google.com, developer.android.com, source.android.com и docs.partner.android.com; The New Stack говорит о семи доменах Google с тем же ключом. Это витрина документации, через которую ежедневно проходят миллионы разработчиков, — то есть потенциальная точка для подмены инструкций и кода примеров.

Хронология: от отчёта до исправления

Отчёт отправлен 6 августа 2026 года, на следующий день Google его проверил и принял. 27 августа определена награда: по данным The New Stack, базовые $75 000 за уязвимость высшей категории S0 в приложении обычного уровня, умноженные на 1,2 за качество отчёта. Исправление вышло только 7 октября — через два месяца после того, как уязвимость была подтверждена. Признаков эксплуатации в публикациях нет.

Что это значит для команд разработки

Подпись Flask-сессии защищает от подделки, но не от чтения: содержимое стандартной cookie-сессии любой может декодировать. Всё, что туда положено, нужно считать публичным. Ключ подписи, попавший к клиенту, обнуляет и эту защиту. А pickle в цепочке превращает подделку данных в выполнение кода — документация Python прямо предупреждает, что распаковывать pickle можно только из полностью доверенного источника.

Отдельный урок — переиспользование секретов. OAuth client_secret и ключ подписи сессий решают разные задачи, и утечка одного не должна автоматически компрометировать другое.

Что проверить в своих Python-сервисах

1. Найдите все вызовы pickle.loads, pickle.load и обёрток над ними (в том числе в сторонних библиотеках сессий и кэшей) и убедитесь, что данные приходят не от клиента. Для сессий и обмена — JSON со схемой валидации.

2. Проверьте, что SECRET_KEY уникален, задан на сервере, хранится в менеджере секретов и не совпадает ни с одним другим ключом или токеном.

3. Декодируйте свои cookie сессий и посмотрите, что в них лежит. Токены, секреты и объекты процессов — на сервер, в хранилище сессий; в cookie — только идентификатор.

4. Если что-то из этого найдено — ротируйте ключи, а не только правьте код: старые подписанные сессии и утёкшие секреты продолжат работать.

Часто задаваемые вопросы

Нужно ли что-то делать пользователям сайтов Google? Нет. Исправление выполнено на стороне Google 7 октября 2026 года, данных об эксплуатации нет.

Это уязвимость во Flask? Нет. Flask работает как задумано: подписанная cookie-сессия читаема клиентом по определению. Ошибка — в том, что положили в сессию и каким ключом её подписали.

Почему pickle так опасен? При распаковке pickle может вызвать произвольную функцию — это заложено в формат. Любые данные, которые мог изменить клиент, превращаются в код.

Есть ли у уязвимости CVE? В опубликованных материалах идентификатор CVE не указан: ошибка была в собственном сервисе Google, а не в распространяемом ПО.

Источники

Simon Köck — How I Found a $90,000 Remote Code Execution Vulnerability in Google (первоисточник, технический разбор и хронология).

The New Stack — Google paid $90,000 for this bug, then waited two months to fix it.

Документация Python — модуль pickle (предупреждение о десериализации недоверенных данных).

Материал подготовлен редакцией YuSMP Group по открытым источникам. Нужна экспертиза по теме или разработка под задачу — обсудим проект.

Найдём небезопасную десериализацию до того, как её найдут за вас

Проверим код Python-сервисов на pickle и опасные загрузчики, разберём хранение секретов и сессий, проверим переиспользование ключей и дадим план исправлений с приоритетами.

Заказать аудит кода