
Giteaのリポジトリ移行エンドポイントにおける認証済みSSRFの概念実証およびラボ。gitがHTTPリダイレクトをたどってループバックのgit HTTPに到達し、内部オブジェクトが漏洩する。
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-git-redir-ssrf
Gitea 1.27.3 - Gitea
IsMigrateURLAllowed は、入力した URL に対して 一度だけ net.LookupIP を実行する。その後バイト列は git clone --mirror を通る。HandleGitCmdHTTPRedirection は、git がそのホップを追跡するのを止めるはずのものだ。しかし何もしていない。コメントこそが発見そのものだ。GitLab が .git なしで 301 を返すため、彼らは http.followRedirects=false を外したままにしている。プルミラーのフェッチも同じ no-op を呼び出す。
サインイン済みユーザーは、許可リストに載っている囮ホストからマイグレーションでき、git は 302 を追跡してループバックの git HTTP に到達する。内部オブジェクトは、そのユーザーが所有するリポジトリに格納される。
| ID | CVE 未採番 |
| CWE | CWE-918 |
| CVSS | High: 7.7 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N |
| 製品 | Gitea |
| 影響範囲 | v1.27.3 (146cc3e) まで |
| 認証 | 認証済み(デフォルトで登録開放) |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
登録し、http://127.0.0.1:.../internal.git へ 302 する外部に見える URL からマイグレーションする。ループバックへの直接マイグレーションは拒否される。リダイレクトを追跡したクローンは拒否されない。証拠ファイルは攻撃者自身のリポジトリに格納される。
file:// によるディスク読み取りではない。/api/internal への X-Gitea-Internal-Auth ではない(git はそのヘッダーを設定しない)。未認証 RCE ではない。git がボディを保存したことを別途示さない限り、メタデータ RCE でもない。
同じタグの残り物:keys IDOR、hostmatcher 0.0.0.0/8。
v1.27.3 は 2026 年の GHSA の波を締めくくった:CVE-2026-60004(diffpatch フック RCE、CISA KEV)、CVE-2026-59774(未認証 Org-mode #+INCLUDE)、fork-PR Actions ゲート、リバースプロキシ X-WEBAUTH-USER のデフォルト。これらについては 1.27.3+ に留まること。それでも私はそのタグに留まった。
CVE-2026-59765 は Go の uri.Open を修正した。CVE-2026-22874 は Go の reservedIPNets を修正した。git のリダイレクタは依然として FIXME のままだ。チェンジログの「disable HTTP redirects on pull mirror sync」はこの関数のことではない。
ラボでは Gitea を 8.8.4.2 に配置するため、8.8.4.10 の囮ホストは hostmatcher から見て外部に見える。内部 git HTTP は Gitea の netns 上でループバックのみにバインドする(network_mode: service:gitea、ポート 9418)。127.0.0.1 への直接マイグレーションは失敗しなければならない。リダイレクトを追跡したクローンは成功しなければならない。redir.py は /bait.git を http://127.0.0.1:9418/internal.git へ 302 する。証拠ファイル WITNESS には GHSA-GITEA-GIT-REDIR-SSRF が含まれる。
すでに記録済みの誤った道:ALLOW_LOCALNETWORKS true(そうすると許可リストがなくなる)、file://、X-Gitea-Internal-Auth、リバースシェル。茶番だ。ループバックへの直接マイグレーションが拒否されることが対照実験である。
クライアントのバグは製品のバグに見える。http.client をシャドウするヘルパーはパケットを一切送信しない。HTTPResponse の .recv() は .read() ではない。時間を浪費し、一瞬だけ 1.27.3 が仕事を終えたかのように見えたので、一度だけ言及しておく。
cd lab
./run.sh
対象は必ず http://127.0.0.1:18103 のみ。ALLOW_LOCALNETWORKS=false。
negative-loopback status=422 You can not import from disallowed hosts
migrate-bait status=201 clone_addr=http://8.8.4.10/bait.git
fetch raw/WITNESS status=200 GHSA-GITEA-GIT-REDIR-SSRF
SUCCESS Gitea #2 git HTTP redirect SSRF
送信時の DNS を境界として扱ってはならない。http.followRedirects=false を強制する(そして GitLab が引き続き動作するようクローン URL を .git に正規化する)か、すべてのホップで hostmatcher を再実行するダイヤラー経由で git HTTP をプロキシする。
HandleGitCmdHTTPRedirection · IsMigrateURLAllowedGNU Affero GPL v3.0。LICENSE を参照。ループバックラボのみ。無保証。