abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-restore-file-open
解説記事: https://abraxaslabs.tech/research/gitea-restore-file-open
Gitea 1.27.3 - Gitea
CVE-2026-59765 は OpenWithClient に hostmatcher 付き HTTP クライアントを導入しました。しかし file:// ブランチはそのクライアントを無視し、os.Open を呼び出します。ダンプのリストアには DownloadFunc がありません。gitea_uploader.go はその後、書き換えられた file:// URL を開きます。os.Open はダンプ側のシンボリックリンクを辿ります。結合パスはダンプ配下に留まりますが、シンボリックリンクは留まりません。
信頼できないダンプをオペレーターがリストアすると、シンボリックリンクのターゲットがリリース添付ファイルにコピーされます。Gitea の uid として、これはサービスアカウントが読み取れる任意のファイルです。
| ID | CVE 未割当 |
| CWE | CWE-73 |
| CVSS | Medium: 4.2 CVSS:3.1/AV:L/AC:L/PR:H/UI:R/S:U/C:H/I:N/A:N |
| 製品 | Gitea |
| 影響範囲 | v1.27.3(146cc3e)まで; ローカルオペレーターによる gitea restore-repo |
| 認証 | 信頼できないダンプのローカルオペレーターによるリストア |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
管理者に、ダンプ配下に結合されるパスの下にシンボリックリンクを含む信頼できないダンプ(「バックアップ」ディレクトリ、信頼できないリモートからのリストアなど)を渡します。リストアはターゲットファイルをリストアされたリポジトリのリリース添付ファイルにコピーします。そのリポジトリを読める者は誰でもそれをダウンロードできます。
ダンプ作成者が app.ini を指定すれば、それは認証情報の窃取となります(INTERNAL_TOKEN、SECRET_KEY、JWT、DB パスワード)。ラボのオラクルは仕込んだ目印ファイルであり、app.ini ではありません。これは OS の LPE ではありません。未認証でもありません。ダンプルートの結合エスケープでもありません。GitHub/GitLab/Gitea からのライブマイグレーションは DownloadFunc を設定し、攻撃者の file:// を os.Open することはありません。
リストア関連のマップが 2 つ、残されたテーブルの上にありました。まず明白な方をラボで検証しました。
Finding 8 はダンプルートの結合エスケープでした。release.yml に絶対パスの DownloadURL を書き込み、FilePathJoinAbs が素朴な filepath.Join(base, "/etc/passwd") のようにダンプのプレフィックスを捨てることを期待するものです。1.27.3 ではそうなりません。各 sub は filepath.Clean("/"+s) の後に filepath.Join(base, cleaned) となります。/tmp/dump + /tmp/GITEA-JOIN-OUTSIDE の結合結果は /tmp/dump/tmp/GITEA-JOIN-OUTSIDE のままでした。リストアは file:// をダンプ配下に書き換え、open ...: no such file or directory で失敗しました。このタグでは結合エスケープにはなりません。
Finding 9 が実際に成立したものです。ダンプの外に目印ファイルを仕込み、ダンプ配下に結合されるパスにシンボリックリンクを置き、gitea restore-repo を実行しました。リストアの rc=0。リストアされたリリース添付ファイルには GITEA-FILE-OPEN-WITNESS が含まれていました。
記録済みの誤った方向性: 絶対パスの DownloadURL によるダンプルートの結合エスケープ; ライブマイグレーションの file:// LFI; X-Gitea-Internal-Auth(リストアは Gitea の uid で実行される CLI であり、/api/internal ではない); リストアの HTTP をリモート未認証とみなすこと(CVSS はローカル、高権限、ユーザー操作); リバースシェル。すべて見せかけです。
cd lab
./run.sh
必ず http://127.0.0.1:18137 のみを対象とすること。Compose は lab/dump を読み取り専用でマウントする。run.sh はコンテナ内に witness を配置し、ダンプをビルドし、シンボリックリンクを設置した後、gitea restore-repo を実行する。
restore-rc=0 Restore repo labadmin/restored successfully
download status=200 snippet=GITEA-FILE-OPEN-WITNESS
SUCCESS GITEA-RESTORE-FILE-OPEN
OpenWithClient から file:// を削除するか、ダンプのシンボリックリンクを辿ることを拒否し、信頼できないダンプを復元しないでください。復元された添付ファイルには、ダンプ外の証拠を含めてはなりません。
uri.go · gitea_uploader.go · FilePathJoinAbsGNU Affero GPL v3.0。LICENSE を参照してください。ループバックラボ専用です。保証はありません。