abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-artifact-v4-readall
Gitea 1.27.3 - Gitea
job_summary.go はすでに MaxJobSummarySize (1 MiB) で io.LimitReader により上限が設定されている。artifact v4 の parseProtobufBody は io.ReadAll(ctx.Req.Body) を上限なしで実行する。CreateArtifact、Finalize、List、Get、Delete はすべてこれを経由する。ランダムなユーザー PAT では不十分。実行中の Actions ジョブトークンが必要。Fork-PR ジョブは 1.27.3 では依然として NeedApproval となる。
Job-summary は LimitReader を学習した。Artifact v4 はそれをコピーしなかった。稼働中のジョブは 12 MiB の CreateArtifact を POST でき、Gitea はそのすべてをバッファリングする。
| ID | CVE 未割当 |
| CWE | CWE-400 |
| CVSS | Medium: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H |
| Product | Gitea |
| Affected | Actions 有効時、v1.27.3 (146cc3e) まで |
| Auth | 実行中の Actions ジョブトークン |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 のみ |
実行中の Actions ジョブ (自身のリポジトリ、またはすでに NeedApproval を通過した fork-PR) から、任意の大きさの v4 CreateArtifact ボディを POST し、Gitea にそのすべてをバッファリングさせることができる。同一インスタンス上の job-summary はすでに 1 MiB を超えるものを拒否している。
これは Gitea プロセスへのメモリ負荷である。ラボでは上限の欠如を証明した (12 MiB -> 200)。プロセスを停止させることはなかった。RCE ではない。未認証でもない。稼働中のジョブなしに盗まれたユーザー PAT ではこの経路に到達しない。
GHSA の波の後に残ったマップには Actions のボディ処理が含まれていた。Fork-PR ジョブは 1.27.3 では依然として NeedApproval となるため、これは未認証の fork-PR スキップではない。Actions API がリクエストボディをどのように読み取るかを調べた。Job-summary には数値がある。Artifact v4 にはない。
gitea/act_runner:0.2.13 を立ち上げ、ジョブトークンが存在するように hold ワークフローを仕込み、12 MiB の CreateArtifact を POST した。HTTP 200 ok と signedUploadUrl。次に 8 MiB の job-summary: 400 invalid summary。GET /api/v1/version は依然として 200。Gitea は稼働し続けた。ラボの mem_limit は 1g。ボディは 12 MiB に制限されているため、ホストが実験対象ではない。ホストエグゼキュータのみ。docker.sock なし。
すでに記録済みの誤った道: ジョブトークンなしの CreateArtifact (401 はバグではない); プロセス kill / OOM (SUCCESS は 12 MiB -> 200 である一方、8 MiB の summary -> 400); signedUploadUrl を RCE とみなすこと; fork-PR 未認証; リバースシェル。茶番である。
cd lab
./run.sh
ターゲットは http://127.0.0.1:18135 のみ。compose 内の ROOT_URL は http://gitea:3000/ であるため、ランナーが登録できる。
v4-create status=200 sent=12582912
v4-unbounded-readall=1
job-summary status=400 sent=8388608 invalid summary cap=MaxJobSummarySize=1048576
gitea-still-up status=200
SUCCESS GITEA-ARTIFACT-V4-READALL
parseProtobufBody を proto サイズの上限で io.LimitReader によりラップする。MaxJobSummarySize と同じパターン。12 MiB の CreateArtifact は、8 MiB の job-summary がすでに失敗するのと同じクラスの方法で失敗しなければならない。
GNU Affero GPL v3.0。LICENSE を参照。ループバックラボのみ。無保証。