28.3.0 — третий поддерживающий выпуск ветки 28, и главное в нём не новые функции, а безопасность. Основная тема — токены с ограниченной областью действия (public-only): проверки для них не применялись на части маршрутов, из-за чего ограниченный токен вёл себя как полный.
Что именно исправлено:
- Административный API. Public-only токен администратора мог перечислять e-mail всех пользователей, создавать приватные организации, регистрационные токены раннеров и новых администраторов.
- Удаление репозиториев.
DELETE /api/v1/orgs/{org}/reposне отклонял ограниченный токен, поэтому владелец организации мог таким токеном снести все её репозитории, включая приватные. - Токен CI-задачи.
GITEA_TOKENвообще не имеет области действия, а фильтры репозиториев воспринимали отрицательный ID системного пользователя Actions как «без фильтра». В итоге задание могло получить список всех приватных репозиториев инстанса. - Секреты через review. Пользователь с правом чтения мог отправить ревью с
commit_id, указывающим на его собственный коммит в том же репозитории, и workflow, запускавшийся по ревью, исполнялся без подтверждения — с секретами репозитория и токеном на запись. Баг нашли в Anthropic. - Регистрация раннера. Ограниченный токен организатора мог создать токен регистрации раннера, а подключённый раннер получал задания с секретами приватных репозиториев.
- Прочее. Хранимая XSS через заголовок
Content-Encodingу артефактов Actions, чтение приватных блобов через OCI mount, утечка приватных организаций в OIDC userinfo, подмена аккаунта приACCOUNT_LINKING = auto.
Сборки теперь делаются на Go 1.27.3, который больше не доверяет части промежуточных сертификатов (CVE-2026-111943) — это влияет на исходящие проверки сертификатов при OAuth2, вебхуках, зеркалах и миграциях.
Отдельно стоит учесть, что часть багов закрывается только на стороне сервера, но старые токены продолжают работать. Поэтому после обновления разумно перевыпустить токены, которые использовались в CI и интеграциях, и проверить журналы на предмет обращений, которых не должно было быть.
28.3.0 is the third maintenance release of the 28 series, and its headline is security rather than features. The dominant theme is public-only tokens: scope checks were missing on a number of routes, so a restricted token behaved like a full one.
What was fixed:
- Admin API. A site administrator’s public-only token could list every user’s email address, create private organisations, runner registration tokens and new administrators.
- Repository deletion.
DELETE /api/v1/orgs/{org}/reposdid not reject a restricted token, so an organisation owner could use one to delete all of the organisation’s repositories, private ones included. - Actions job token.
GITEA_TOKENcarries no scope at all, and repository filters treated the negative ID of the Actions system user as “no owner filter”. A job could therefore list every private repository on the instance. - Secrets via review. A user with read access could submit a review whose
commit_idpointed at their own commit in the same repository; the review-triggered workflow then ran without approval, with the repository’s secrets and a write token. Anthropic reported this one. - Runner registration. An owner’s restricted token could mint an organisation runner registration token, and the runner that joined received jobs, including their secrets, from private repositories.
- Also. Stored XSS through the
Content-Encodingheader on Actions artifacts, reading private blobs via OCI cross-repository mount, private organisations leaking through the OIDC userinfo endpoint, and account takeover withACCOUNT_LINKING = auto.
Binaries are now built with Go 1.27.3, which no longer trusts a set of intermediate certificates (CVE-2026-111943). That affects outgoing certificate checks for OAuth2 providers, webhooks, mirrors and migrations.
Note that some fixes only apply on the server side while old tokens keep working. After upgrading, it is worth reissuing tokens used by CI and integrations and reviewing logs for requests that should never have happened.