Как запись в репозиторий Gitea превращается в удалённое выполнение кода?

Gitea закрыла критическую уязвимость удалённого выполнения кода CVE-2026-60004 с оценкой 9,8 по шкале CVSS. Ошибка затрагивает выпуски начиная с Gitea 1.17 и вплоть до 1.27.0 включительно; исправление вошло в Gitea 1.27.1. Пользователь с обычным правом записи в репозиторий мог превратить содержимое подготовленного патча в действующий Git-хук и запускать команды оболочки от имени системной учётной записи службы Gitea. Уязвимость обнаружил исследователь Shai Rod, известный как NightRang3r; Gitea официально указала его автором сообщения об ошибке.
Атака проходит через запрос POST /api/v1/repos/{owner}/{repo}/diffpatch. Этот маршрут вызывает reqToken(), поэтому анонимный запрос будет отклонён: к моменту обращения к API пользователь должен войти в систему и иметь право записи в выбранный репозиторий. На стандартной установке получить эти права порой несложно. Gitea по умолчанию оставляет регистрацию открытой, не требует подтверждать электронную почту или ждать ручного одобрения, не помечает новые учётные записи как ограниченные и не задаёт лимит на создание репозиториев. Посторонний посетитель способен зарегистрироваться, создать собственный репозиторий и сразу получить нужный уровень доступа. Заранее украденные или выданные администратором реквизиты ему при такой конфигурации не нужны.
Причина CVE-2026-60004 скрывалась в обработке пользовательского патча внутри общего временного клона репозитория. В уязвимых версиях этот клон был bare-репозиторием, то есть не имел отдельного рабочего дерева. Gitea запускала git apply с параметрами --index, --recount, --cached и --binary. При использовании Git 2.32 или новее к команде добавлялся параметр -3, включающий попытку трёхстороннего слияния, если патч нельзя применить обычным способом. Именно это запасное поведение Git и позволило выйти за предполагаемые рамки операции с индексом.
Эксплуатация строится на двукратной отправке одного вредоносного патча. Повтор создаёт конфликт типа add/add, после чего трёхсторонний режим -3 извлекает указанный в индексе путь на диск, хотя команда содержит --cached. У bare-клона корень каталога совпадает с $GIT_DIR. Поэтому подготовленный исполняемый файл удаётся записать по адресу hooks/post-index-change. Git воспринимает его как штатный хук post-index-change и запускает во время обновления индекса. Команды внутри файла получают те же системные права, с которыми работает служба Gitea.
Для успешной атаки должны совпасть несколько условий: версия Gitea находится в диапазоне 1.17–1.27.0, установлен Git 2.32 или более поздний, маршрут diffpatch доступен, временная файловая система разрешает запись и исполнение файлов, а атакующий имеет право записи в репозиторий. Открытая регистрация лишь помогает внешнему пользователю добыть такое право; сама уязвимость остаётся доступной любому уже существующему автору репозитория. Если временный каталог смонтирован с запретом исполнения, описанная цепочка может оборваться на запуске хука, но это не исправляет ошибочную обработку патча.
В опубликованной 28 июля 2026 года рекомендации Gitea присутствует готовый публичный proof of concept, или PoC. Код входит под обычной пользовательской учётной записью, создаёт и инициализирует закрытый репозиторий, дважды отправляет вредоносный патч, запускает команды через внедрённый Git-хук и получает их результат. Обратное подключение к серверу атакующего для этого не требуется. Хук сохраняет вывод команд в объектах Git, формирует ветку с результатами, после чего автор атаки забирает её через аутентифицированный протокол smart HTTP.
Команды выполняются не с правами root автоматически, а от имени системной или служебной учётной записи Gitea. Масштаб ущерба зависит от изоляции процесса. Под угрозой оказываются секреты приложения и переменные окружения, подключённые репозитории, реквизиты и содержимое базы данных, данные OAuth, а также внутренние сервисы, доступные с сервера Gitea. Даже непривилегированная служебная учётная запись часто имеет достаточно доступа, чтобы читать исходный код, токены и конфигурацию либо обращаться к закрытым сетевым узлам.
Постоянное исправление одно: обновление до Gitea 1.27.1 или более новой версии. Разработчики заменили временный bare-клон на обычный, non-bare-клон. В коде появился прямой комментарий о том, что команды Git с параметром --index могут затрагивать рабочее дерево. Изменение объединили и перенесли в поддерживаемую ветку 26 июля 2026 года. На следующий день, 27 июля, Gitea сообщила, что экземпляры Gitea Cloud будут обновлены автоматически.
Исправление легко пропустить при беглом чтении журнала изменений. В примечаниях к выпуску его поместили в раздел MISC, а не SECURITY, под невнятным описанием «рефакторинг: применение патча Git» — переводом записи "refactor: git patch apply". В исходном тексте также сохранилась оборванная фраза «Версия 1.27. Примечания к выпуску...». По контексту речь идёт о примечаниях к 1.27.1, хотя номер там указан не полностью.
Хронология заняла три дня: 26 июля 2026 года исправление объединили и бэкпортировали, 27 июля объявили об автоматическом обновлении Gitea Cloud, а 28 июля выпустили рекомендацию с публичным PoC. В самой рекомендации не сказано, что атаки уже наблюдались. По состоянию на 29 июля 2026 года ни один из упомянутых первичных источников не сообщал, эксплуатировалась ли CVE-2026-60004 до выхода версии 1.27.1 или после него. Статус реальных атак на эту дату оставался неизвестным.
NightRang3r показывал эту RCE вместе с отдельной уязвимостью включения файлов. В её PoC с узла под управлением Gitea 1.27.0 извлекался файл /etc/passwd. Судя по отдельному изменению, вошедшему в 1.27.1, проблема находилась в обработчике Org-mode: после исправления пути, переданные через +INCLUDE, возвращаются как обычный текст, а не читаются из файловой системы сервера. Gitea не выпустила для этой ошибки отдельную рекомендацию и не присвоила ей отдельный CVE. Она отлична от CVE-2026-60004, хотя обе проблемы были закрыты изменениями в версии 1.27.1.
До установки обновления администратору стоит закрыть открытую регистрацию, ограничить создание репозиториев и выдачу прав записи, проверить возможность отключения маршрута diffpatch и запретить исполнение файлов во временных каталогах, если это не ломает работу сервиса. Эти меры не защищают от уже зарегистрированных авторов репозиториев и не заменяют обновление. Проверки требуют обращения к diffpatch, неожиданные файлы в каталогах Git-хуков и подозрительные ветки с выводом команд. Отдельной ревизии заслуживает доступ служебной учётной записи Gitea к переменным окружения, секретам приложения, базам данных, OAuth-реквизитам, смонтированным репозиториям и внутренним сетевым сервисам.[/final]


Новое на сайте

Ссылка