
Разбор CVE-2026-22874: неполный разрешённый список (allow-list) для SSRF в Gitea webhook/миграции (переход на IPv6 и облачные метаданные). Исправлено в Gitea 1.26.3.
Технический разбор и ссылки по CVE-2026-22874 (GHSA-2r5c-gw76-rh3w): неполный список разрешений SSRF в доставке вебхуков и миграции репозиториев Gitea, исправленный в Gitea 1.26.3.
Я независимо сообщил об этом классе SSRF мейнтейнерам Gitea и указан как контрибьютор (other) в опубликованном бюллетене; основной автор бюллетеня — J. Leitschuh. Этот репозиторий — защитный, образовательный разбор публичного бюллетеня; проблема уже исправлена.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N)<= 1.26.2 — Исправлено: 1.26.3Список разрешений SSRF Gitea по умолчанию (MatchBuiltinExternal, используемый как при доставке вебхуков, так и при миграции репозиториев) полагался на из стандартной библиотеки Go, которая распознаёт только RFC 1918 (, , ) и RFC 4193 (). Некоторые диапазоны адресов, часто используемые для облачных сервисов метаданных, внутренних сетей и механизмов перехода на IPv6, не являются «приватными» согласно этому определению и потому проходили фильтр «внешних» адресов, позволяя аутентифицированному пользователю заставлять сервер отправлять HTTP-запросы на эти адреса.
net.IP.IsPrivate()10/8172.16/12192.168/16fc00::/7Поскольку доставка вебхуков записывает статус ответа, заголовки и до ~1 МиБ тела и отображает их в интерфейсе истории вебхуков, SSRF не является слепым: атакующий может прочитать то, что возвращает целевой внутренний сервис.
net.IP.IsPrivate()| Диапазон | Значение |
|---|---|
100.64.0.0/10 | RFC 6598 NAT операторского класса |
168.63.129.16/32 | Azure WireServer / эндпоинт метаданных экземпляра |
64:ff9b::/96 | RFC 6052 NAT64 (может встраивать 169.254.169.254, например AWS IMDS) |
2001::/32 | RFC 4380 Teredo |
2002::/16 | RFC 3056 6to4 |
IPv4-отображаемые IPv6-формы перечисленных выше адресов уязвимы таким же образом.
Таким образом, аутентифицированный пользователь, способный создавать или изменять вебхуки (или запускать миграцию), может получить доступ к облачным эндпоинтам метаданных — например, к AWS IMDS через NAT64-маппинг или к Azure WireServer по адресу 168.63.129.16 — а также к сервисам, доступным только из внутренней сети, и затем прочитать ответ через просмотр истории вебхуков.
Политикой по умолчанию является MatchBuiltinExternal в проверке HostMatchList Gitea, которая считала разрешённым любой глобальный unicast-адрес, не проходящий проверку IsPrivate():
case MatchBuiltinExternal:
if ip.IsGlobalUnicast() && !ip.IsPrivate() {
return true
}
net.IP.IsPrivate() не является границей безопасности для определения «внешнего» адреса: он не учитывает NAT операторского класса, облачные эндпоинты метаданных или переходные IPv6-диапазоны, которые могут маршрутизироваться к внутренним узлам или узлам метаданных.
Исправлено в Gitea 1.26.3 путём расширения встроенного фильтра для блокировки указанных выше дополнительных диапазонов. Операторам следует обновиться до версии 1.26.3 или новее. В качестве эшелонированной защиты: