
Proof-of-Concept-Lab für eine Gitea-Autorisierungsumgehung, bei der ein nur-öffentlicher PAT mit write:organization über POST /api/v1/orgs eine private Organisation erstellt.
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-public-only-pat-org
Gitea 1.27.3 - Gitea
public-only bei einem PAT soll das Versprechen sein, dass das Token keine privaten Ressourcen berühren kann. POST /user/repos hat rejectPublicOnly. POST /orgs hat tokenRequiresScopes und reqToken. Es hat kein rejectPublicOnly. DEFAULT_ALLOW_CREATE_ORGANIZATION ist standardmäßig true.
Ein public-only PAT mit write:organization erstellt eine private Organisation. Dasselbe Token kann kein privates Benutzer-Repository erstellen.
| ID | noch keine CVE |
| CWE | CWE-863 |
| CVSS | Medium: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| Produkt | Gitea |
| Betroffen | bis v1.27.3 (146cc3e) |
| Auth | public-only PAT mit Org-Schreibrechten |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Ein gestohlenes oder übermäßig ausgestelltes public-only PAT verwenden, das zusätzlich write:organization besitzt. Eine private Organisation erstellen. Diese Org ist ein Versteck, das das Token eigentlich nicht hätte anlegen dürfen. Dasselbe Token kann weiterhin kein privates Benutzer-Repository erstellen, und dieser Bug öffnet nicht das bestehende private Git von jemand anderem.
Integrität, kein Private-Git-Dump. Nützlich, wenn das Opfer „public-only" absichtlich ausgestellt hat: CI, ein Bot, ein Contractor-Token, von dem es dachte, es könne keine private Org wachsen lassen.
Das Erstellen von Org-Repos prüft nur die Sichtbarkeit der Org. Das veraltete POST /org/{org}/repos überspringt public-only vollständig. Ich habe das Erstellen von Orgs im Lab getestet. Das reicht.
Derselbe übrig gebliebene Durchgang wie beim hostmatcher 0.0.0.0/8-Lab: v1.27.3 nach der GHSA-Welle, dann die Handler, die noch ein Gate überspringen, das ein Geschwister bereits hat. Sichtbarkeits- und Token-Scope-Bugs waren ein Thema dieser Welle. Ich habe rejectPublicOnly in api.go gegrept. Das Erstellen von Benutzer-Repos hat es. Das Erstellen von Orgs nicht.
Ich habe ein PAT mit den Scopes public-only,write:organization,write:repository,write:user erstellt. Das Erstellen einer privaten Org lieferte 201. Dasselbe Token, Erstellen eines privaten Benutzer-Repos, 403 this endpoint is not available for public-only tokens. Diese 403 ist die Kontrolle. Wenn beide 201 geliefert hätten, wäre die Middleware vollständig verschwunden. Wenn beide 403 geliefert hätten, gäbe es nichts zu melden.
Bereits dokumentierte Irrwege: org HTTP 201 als ausreichend zu betrachten (bei GET visibility=private bestätigen); erfolgreiches Erstellen eines privaten Benutzer-Repos (dann ist rejectPublicOnly verschwunden - das Lab erfordert 403); Lesen bestehender privater Git-Inhalte; eine Reverse Shell. Theater.
cd lab
./run.sh
Ziel nur http://127.0.0.1:18132. Compose setzt DEFAULT_ALLOW_CREATE_ORGANIZATION=true.
token-scopes=public-only,write:organization,write:repository,write:user
org-create status=201
org-visibility='private'
user-repo-create status=403 this endpoint is not available for public-only tokens
SUCCESS GITEA-PUBLIC-ONLY-PAT
rejectPublicOnly() auf POST /orgs setzen und das Erstellen von Org-Repos ebenfalls als public-only-sensibel behandeln. Das Erstellen einer public-only-Org muss genauso 403 liefern, wie es das Erstellen eines privaten Benutzer-Repos bereits tut.
api.go (rejectPublicOnly, POST /orgs, POST /user/repos)GNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.