
Proof-of-Concept-Lab, das eine authentifizierte SSRF in Giteas hostmatcher-Allow-List demonstriert, bei der ein Webhook an http://0.0.0.1 Loopback-Dienste erreicht, die 127.0.0.1 nicht erreichen kann.
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-hostmatcher-0000-ssrf
Gitea 1.27.3 - Gitea
CVE-2026-22874 fügte reservedIPNets hinzu. CGNAT, TEST-NET, NAT64, Teredo, Azure WireServer. Echte Bereiche. Nicht RFC 6890 0.0.0.0/8, der alte "this network"-Block. IANA veröffentlicht ihn weiterhin. Gos IsGlobalUnicast ist true für 0.0.0.1. Es ist nicht IsLoopback (127.0.0.0/8). Es ist nicht IsPrivate. Die standardmäßige externe Allow-List behandelt es als das öffentliche Internet. Linux wird 0.0.0.1 an einen lokalen Socket zustellen, wenn diese Adresse auf lo liegt. Derselbe Listener, zwei Namen.
Ein angemeldeter Benutzer kann einen Webhook auf http://0.0.0.1 setzen und den HTTP-Body aus der Hook-Historie lesen. 127.0.0.1 auf demselben Port wird verweigert.
| ID | noch keine 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 |
| Produkt | Gitea |
| Betroffen | bis v1.27.3 (146cc3e); Überbleibsel von CVE-2026-22874 |
| Auth | angemeldeter Benutzer, der einen Repo-Webhook erstellen kann |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Registrieren (standardmäßig offene Registrierung), ein Repo erstellen, einen Webhook auf http://0.0.0.1:<local-port>/ richten, ihn testen und den Response-Body aus der Hook-Historie lesen. Das ist Loopback-HTTP, das 127.0.0.1 auf demselben Port nicht erreichen kann: alles, was im Netns von Gitea lauscht und breiter als Loopback gebunden ist, einschließlich Diensten, die der Betreiber für "nur localhost" hielt, weil sie 127.0.0.0/8 blockierten.
Es setzt kein X-Gitea-Internal-Auth. Es ist für sich genommen kein RCE. Es ist ein vollständiger HTTP-Body von einer Adresse, die die Allow-List weiterhin als extern bezeichnet.
v1.27.3 ist der Build, der die GHSA-Welle 2026 geschlossen hat. Ich bin trotzdem auf diesem Tag sitzen geblieben. Patches, die eine Allow-List oder eine Deny-List hinzufügen, sind ein Geschenk: Man liest die Liste und fragt dann, was IANA noch hat, das die Liste vergessen hat. Zwei Überbleibsel hatten bereits Labs auf diesem Tree (keys IDOR und git-redirect SSRF). Die Überbleibsel-Tabelle in diesem Post listete einen Webhook auf http://0.0.0.1/ als Karte. Dies ist der SUCCESS.
Die Webhook-Zustellung speichert den HTTP-Body in der Hook-Historie. Das ist ein besserer Orakel als git clone, das größtenteils nur "hat der Fetch funktioniert" ist. Ich habe ein Orakel im Netns von Gitea auf Port 8080 platziert, 0.0.0.1/8 auf lo mit NET_ADMIN hinzugefügt und zwei Webhooks erstellt. Zuerst die Negativkontrolle.
Bereits dokumentierte Irrwege: Webhook-Erstellung HTTP 201 als Orakel zu behandeln (die Historie ist das Orakel); erfolgreiche Zustellung an 127.0.0.1 (das wäre ein anderer Bug - das Lab erfordert, dass sie verweigert wird); /api/internal mit X-Gitea-Internal-Auth anzusprechen; eine Reverse Shell. Theater. Der Zeuge ist GITEA-0000-SSRF in der Hook-Historie.
cd lab
./run.sh
Ziel nur http://127.0.0.1:18131. Das Orakel teilt sich das Netns von Gitea auf Port 8080. run.sh fügt 0.0.0.1/8 auf lo hinzu.
create-hook name=neg-loopback status=201
negative-control 127.0.0.1 blocked
create-hook name=hit-0000 status=201
poll id=2 witness=True
SUCCESS GITEA-HOSTMATCHER-0000
Füge 0.0.0.0/8 zu reservedIPNets hinzu oder höre auf, IsGlobalUnicast als "sicher zum Anwählen" zu behandeln. 0.0.0.1 muss genauso verweigert werden wie 127.0.0.1.
hostmatcher.goGNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.