
Forgejo 16.0.5 – Hoch – Remote – SSRF – OpenID-Discovery ruft angreiferkontrollierte URLs ab
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · forgejo-openid-discovery-ssrf
Klasse: SSRF Reichweite: Remote
Forgejo 16.0.5 (8d24b7d) - Forgejo
Wenn [openid] ENABLE_OPENID_SIGNIN aktiviert ist, übergibt ein unauthentifiziertes POST /user/login/openid die Angreifer-URL an yohcop openid-go v1.0.1. Die paketweiten Hilfsfunktionen dieser Bibliothek verwenden http.DefaultClient. Auf diesem Pfad gibt es keinen Hostmatcher. Webhooks und Migrationen filtern ausgehendes HTTP. OpenID nicht.
Wer das Anmeldeformular erreichen kann, kann einen Yadis-GET gegen Loopback, RFC1918, CGNAT und IMDS vom Forgejo-Host aus steuern.
| ID | noch keine CVE |
| Klasse | SSRF |
| Reichweite | Remote (unauthentifiziert, wenn OpenID-Anmeldung aktiviert ist) |
| CWE | CWE-918 |
| CVSS | Hoch: 8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Produkt | Forgejo |
| Betroffen | bis v16.0.5 (8d24b7d) mit ENABLE_OPENID_SIGNIN; Überbleibsel von Gitea CVE-2026-58314 |
| Auth | unauthentifiziert |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Kein Konto. Eine OpenID-URL per POST senden. Der Forgejo-Host ruft sie ab.
| Privileg | Methode / Sink | Recon / Integrität / Verfügbarkeit | Im Lab bewiesen oder abgeleitet |
|---|---|---|---|
| Einen Yadis-GET gegen Loopback steuern | Unauth POST /user/login/openid mit openid=http://127.0.0.1:18080/ | Recon (ausgehendes HTTP vom Forgejo-Host) | Im Lab bewiesen. Oracle sah GET / mit Accept: application/xrds+xml von 127.0.0.1 |
| RFC1918, CGNAT, Link-Local, IMDS sondieren | Derselbe http.DefaultClient Discover, kein IP-Filter | Recon | Vom Client abgeleitet. Lab verwendete nur Loopback |
| Wiederholen von einem angemeldeten Add-OpenID | POST /user/settings/security/openid ruft ebenfalls RedirectURL auf und überspringt allowedOpenIDURI | Recon | Vom Handler abgeleitet. Lab verwendete den unauth Login-POST |
| Response-Bodies im Login-Fehler lesen | Nach CVE-2021-45325 geben Fehler den Abruf nicht mehr aus | Recon | Im Lab bewiesen geschlossen. Dieses Überbleibsel ist die Anfrage, kein HTML-Leak |
Geschlossen auf diesem Pin: OpenID-Assoziations-CSRF (openIDState Session-Nonce), Webhook/Migrate-Hostmatcher (dort weiterhin verwendet), git followRedirects=false, Migrate LookupIP CVE-2026-82556. Das Lab schließt keine OpenID-Anmeldung ab und liefert keine Shell zurück.
Die Checkbox des Web-Installers ist standardmäßig aktiviert (EnableOpenIDSignIn = MustBool(!InstallLock) solange entsperrt, dann in app.ini geschrieben). Nach dem Lock ist ein fehlender Schlüssel false. Das Docker-app.ini-Template hat keinen [openid]-Abschnitt, also ist ein vorab gesperrtes Image ohne den Wizard aus, es sei denn der Betreiber setzt den Schlüssel. Leere WHITELISTED_URIS erlaubt jede URI.
v16.0.5 schloss die OpenID-Assoziations-CSRF. Ich blieb trotzdem auf dieser Oberfläche. Gitea PR 38406 / CVE-2026-58314 setzte einen hostmatcher-gefilterten Client in eine dedizierte openid-go-Instanz. Dieser Pin ruft weiterhin die paketweiten Hilfsfunktionen auf.
Bereits dokumentierte Irrwege: erneutes Melden der Assoziations-CSRF (diese Nonce ist im Tree); ein vorab gesperrtes Docker-Image als Standard zu behandeln (der Wizard schreibt die Checkbox an); das alte OpenID-Fehlerstring-Leak zu erwarten; eine Reverse Shell. Theater.
python3 forgejo-openid-discovery-ssrf-Abraxas-Labs.py
oder:
cd lab
./run.sh
Ziel nur http://127.0.0.1:19330. Image codeberg.org/forgejo/forgejo:16.0.5. Oracle teilt den Forgejo-Netns und bindet 127.0.0.1:18080.
IOC post-openid status=200
IOC xrds-hits count=1
SUCCESS forgejo-openid-discovery-ssrf how=live post=/user/login/openid openid=http://127.0.0.1:18080/ path=/ accept=application/xrds+xml peer=127.0.0.1 post-status=200 FORGEJO-OPENID-DISCOVERY-WITNESS
Derselbe wie Gitea PR 38406: ein hostmatcher-gefilterter http.Client in eine dedizierte openid-go-Instanz. WHITELISTED_URIS als zweites Gate beibehalten. Loopback, RFC1918, CGNAT, Link-Local und Metadaten blockieren.
modules/auth/openid/openid.goGNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.