Перейти к содержанию

Чужой JWT с edge-платформы: чем обернулась ставка на изоляты V8 вместо процессов

Опубликовано
  • Админы
Утечка данных между изолятами Cloudflare Workers
Скорость и точность утечки по данным препринта arXiv:2608.17043

Бессерверные платформы продали разработчикам скорость холодного старта. Заплатили за неё границей между арендаторами: там, где раньше стоял отдельный процесс, теперь стоит движок JavaScript. Насколько прочна такая граница, 17 августа померили в препринте «Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers».

Результат группы в составе Мартина Шварцля, Хаочэна Сяо, Альберта Педерсена, Сэма Эйнсворта и Найджела Топхэма выглядит так: из памяти постороннего воркера на Cloudflare Workers был извлечён JWT, скорость извлечения — 12 бит в секунду при точности 99,16 %. В Cloudflare говорят, что соответствующие меры внедрены ещё в 2025-м.

Ставка, которую сделала платформа

Персонального процесса на клиента в Workers нет, и это выбор осознанный. Формулировка из документации самой компании: «if Cloudflare had to run a separate process for every guest, the number of tenants Cloudflare could support would be drastically reduced». Разделяют арендаторов изоляты V8 — то есть ядро операционной системы к разграничению отношения не имеет, за него отвечает движок JavaScript.

ℹ️ СПРАВКА

Изолят V8 — отдельный экземпляр движка с собственной кучей и собственным глобальным объектом. В пределах процесса их бывает несколько тысяч. Код на JavaScript разделён между ними полностью; процессор же видит общую физическую память и общие кеши.

Именно в эту щель и бьёт Spectre: про изоляты спекулятивное выполнение не осведомлено, оно оперирует адресами. Дополнительная мера у Cloudflare есть — «кордоны», при которых арендаторы разных тарифов попадают в разные экземпляры рантайма. Соседство внутри одного кордона это, впрочем, не отменяет.

История в двух актах

Ирония в том, что пробитую защиту сконструировали те же люди. Акт первый — 2021 год: Шварцль с соавторами продемонстрировали утечку в 120 бит в час и тут же предложили лекарство под названием Dynamic Process Isolation. Идея экономная: отселять в персональный процесс не всех подряд, а только воркеров с подозрительными показаниями счётчиков производительности; заявленная доля ложных срабатываний — 0,61 %.

Акт второй — нынешняя работа, и вердикт в ней короткий: «the production implementation of DyPrIs was insufficient».

Разницу в скорости полезно перевести в бытовые единицы. Двенадцать бит в секунду складываются в 43 200 бит за час — трёхсоткратный с лишним отрыв от прошлого результата, если быть точным, в 360 раз. Возьмём токен размером 300 байт, то есть 2400 бит: на прежней скорости его выкачивали бы двадцать часов, на нынешней хватит примерно трёх с половиной минут. Это уже не лабораторная демонстрация, а пригодное для работы окно. Оговорюсь: пересчёт здесь мой, в препринте подобной оценки нет.

Чем меряли время там, где часов не выдают

Ограничения рантайма Cloudflare Workers и способ их обхода
Слева — ограничения по документации Cloudflare, справа — подход препринта

Кеш-атака без измерения времени невозможна, и гайки на этом направлении в Workers затянуты давно. Вызов Date.now() во время исполнения кода стоит на месте: значение сдвигается только после операции ввода-вывода. Потоки недоступны, SharedArrayBuffer недоступен, а значит и кустарный счётчик через гонку двух потоков собрать не из чего.

Обход авторы построили на выносе часов наружу: замеры делает сервер атакующего по сетевым ответам, а перед этим односбитовая разница раздувается микроархитектурным усилением до масштаба, различимого через сеть. Детали механики приводит The Hacker News — по его разбору, удалённым таймером служит обмен по WebSocket, а изолят не даёт умереть между запросами Durable Objects. В абстракте препринта этих подробностей нет.

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

Согласованное раскрытие, судя по абстракту, привело к трём изменениям: ограничения V8 Sandbox, переработанное обнаружение внутри DyPrIs и аппаратное запирание кучи арендатора через memory protection keys. Часть перечисленного разобрана в корпоративном блоге — запись «Safe in the sandbox» датирована 25 сентября 2025 года. Тезис про отсутствие следов эксплуатации на протяжении трёх лет стоит держать в уме именно как позицию вендора: независимой проверки не было.

⚠️ ОСТОРОЖНО

Схема «атака → защита → обход защиты» отработала уже второй круг. У Cloudflare на этот счёт есть честная строчка в документации: «Spectre does not have an official solution. Not even when using heavyweight virtual machines». Ни одну мультиарендную платформу считать защищённой окончательно нельзя.

И вывод отсюда следует более широкий, чем «у Cloudflare нашли баг». Изоляция средствами языка обходится дешевле процессной, поэтому её берут везде, где нужна плотность: виртуальный хостинг, чужие бессерверные рантаймы, ваш собственный сервис, гоняющий пользовательский JavaScript внутри одного процесса Node. Как только в модели угроз появляется сосед по железу, реальная граница проходит совсем не по тем линиям, которые видны в коде.

✅ КАК ПРАВИЛЬНО

  • Выяснить фактический срок жизни выдаваемых токенов: чем он меньше, тем уже окно для неспешной утечки.
  • Долгоживущие ключи в памяти edge-функций не держать — запрашивать по мере надобности и не складывать в глобальную область изолята.
  • Под по-настоящему чувствительные вычисления подбирать среду с процессной или аппаратной границей, а не с языковой.
JWT='eyJhbGciOi...'   # свой токен
python3 - <<'EOF'
import base64, json, os
t = os.environ["JWT"].split(".")[1]
p = json.loads(base64.urlsafe_b64decode(t + "=" * (-len(t) % 4)))
print("iat", p.get("iat"), "exp", p.get("exp"), "→ живёт", p["exp"] - p["iat"], "с")
EOF

Перед запуском переменную нужно экспортировать: export JWT='...'. Расхождение exp и iat в сутках означает, что окно для медленного вычитывания у атакующего практически неограниченное. Расхождение в минутах — что похищенный токен протухнет раньше, чем его успеют дочитать.


Источники

💬 ВОПРОС К СООБЩЕСТВУ

Входит ли сосед по железу в вашу модель угроз — или расчёт всё-таки на то, что провайдер разберётся сам? И встречался ли кто-нибудь с обратным переездом: с бессерверной платформы обратно на свой VPS именно из-за подобных исследований?

Featured Replies

No posts to show

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

Последние посетители 0

  • Ни одного зарегистрированного пользователя не просматривает данную страницу
Яндекс.Метрика

Account

Navigation

Поиск

Поиск

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.