CVE-2026-22874(GHSA-2r5c-gw76-rh3w)に関する技術解説と参考情報です。GiteaのWebhook配信およびリポジトリマイグレーションにおけるSSRF許可リストの不完全性に関するもので、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.3GiteaのデフォルトのSSRF許可リスト(Webhook配信とリポジトリマイグレーションの両方で使用される MatchBuiltinExternal)は、Go標準ライブラリの net.IP.IsPrivate() に依存していました。この関数が認識するのはRFC 1918(、、)とRFC 4193()のみです。クラウドメタデータサービス、内部ネットワーク、IPv6移行メカニズムで一般的に使用されるいくつかのアドレス範囲は、この定義では「プライベート」ではないため「外部」フィルタを通過し、認証済みユーザーがサーバーにそれらの宛先へのHTTPリクエストを発行させることができました。
10/8172.16/12192.168/16fc00::/7Webhook配信はレスポンスのステータス、ヘッダー、および最大約1 MiBのボディを記録し、Webhook履歴UIに表示するため、この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形式も同様に影響を受けます。
したがって、Webhookを作成または変更できる(またはマイグレーションを開始できる)認証済みユーザーは、クラウドメタデータエンドポイント(たとえばNAT64マッピング経由のAWS IMDS、または 168.63.129.16 のAzure WireServer)や内部専用サービスに到達し、Webhook履歴ビューを通じてレスポンスを読み取ることができます。
デフォルトのポリシーは、Giteaの HostMatchList チェックにおける MatchBuiltinExternal であり、グローバルユニキャストかつ IsPrivate() でないアドレスをすべて許可として扱います。
case MatchBuiltinExternal:
if ip.IsGlobalUnicast() && !ip.IsPrivate() {
return true
}
net.IP.IsPrivate() は「外部」のセキュリティ境界ではありません。キャリアグレードNAT、クラウドメタデータエンドポイント、内部またはメタデータ宛先にルーティングされる可能性のあるIPv6移行レンジを考慮していないためです。
Gitea 1.26.3 で、上記の追加レンジをブロックするように組み込みフィルタを拡張して修正されました。運用者は1.26.3以降にアップグレードしてください。多層防御として: