Один точечный символ и всё рушится: как «;» почти привёл к RCE на GitHub

Один точечный символ и всё рушится: как «;» почти привёл к RCE на GitHub
 

Небольшой символ — точка с запятой — едва не позволил любому авторизованному пользователю с правом push выполнить произвольную команду на серверах GitHub и GHES. Инцидент, обнаруженный исследователями из Wiz и зафиксированный как CVE20263854, не только показал уязвимость в конкретной обработке заголовков, но и вскрыл системную проблему: многослойные внутренние доверительные допущения в облачных многоарендных платформах.

Как это работало — по шагам

Входная цепочка: push → babeld → gitauth → gitrpcd → prereceive hook

Когда вы выполняете git push, запрос проходит через собственный gitпрокси GitHub — babeld. Он спрашивает gitauth, какие правила применить к этому push (например, лимиты размера файлов, правила ветвления, конфигурация hook). babeld упаковывает эти правила в внутренний заголовок X-Stat (строка вида key=value;key2=value2;…) и пересылает дальше в gitrpcd. Вся последующая логика (включая prereceive hooks) доверяет значениям из X-Stat — эти поля выступают как «паспорт» запроса.

Проблема — парсер и «последний записавшийся выигрывает»

babeld копировал туда и пользовательские push options без фильтрации символов-разделителей. А X-Stat использует ; как разделитель полей. Если attacker вставлял в push option ;large_blob_rejection_enabled=bool:false, то в X-Stat появлялся повторяющийся ключ large_blob_rejection_enabled — и в парсере правило «последняя запись перекрывает предыдущую» приводило к тому, что безопасный флаг true был заменён на false. Таким образом отключался контроль размера загружаемых blob’ов — первый шаг в атаке.

От обхода лимитов — к выполнению кода

Wiz последовательно использовали инъекции полей:

Отключение песочницы через инъекцию поля rails_env (значение отличное от production — обход изоляции).

Переопределение директории поиска hook’ов (custom_hooks_dir) на место, контролируемое атакующим.

Подстановка repo_pre_receive_hooks с путём, ведущим к исполнению произвольного бинарника (path traversal).

В результате в тестовом GHES исследователи получили ответ сервера с uid=500(git) — доказательство того, что payload исполнялся на сервере от имени системного gitпользователя. На GitHub.com полная цепочка сработала после дополнительной инъекции, меняющей режим «enterprise» — там эта ветка исполнения по умолчанию должна была отсутствовать, но изза рассинхронизации деплойной логики часть «неproduction» кода попала в образ.

Wiz подчёркивают, что в их случае не было чтения чужих репозиториев — но наличие возможности исполнять команды под gitаккаунтом на узле означает, что теоретически такие узлы имеют доступ к индексам и содержимому множества репозиториев на той машине.

Последствия для SaaS и GHES

GitHub.com быстро исправил уязвимость: от обнаружения до патча прошло порядка 75 минут. Но с GHES (selfhosted GitHub Enterprise Server) ситуация хуже: на момент публикации 88% GHESинстанций ещё не были обновлены.

Для администраторов GHES GitHub рекомендует срочно обновиться до поддерживаемой версии (выпуски с исправлениями: 3.14.25, 3.15.20, 3.16.16, 3.17.13, 3.18.7, 3.19.4 и 3.20.0+). Также нужно искать в логах auditжурнала потенциальные записи с push options, содержащими ;, и проверять, не было ли несанкционированных инъекций.

Wiz Research: GitHub RCE (CVE20263854)

БОЛЬШЕ ИНФОРМАЦИИ

Email

sms_systems@inbox.ru

Телефон

+ 7 (985) 982-70-55

Если у вас есть инновационная идея, мы будем рады реализовать ее для Вас!

Специалисты нашей кампании и наши разработки для вас!