
Forgejo 16.0.5 - Alta - Remota - SSRF - El descubrimiento de OpenID obtiene URLs controladas por el atacante
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · forgejo-openid-discovery-ssrf
Clase: SSRF Alcance: Remoto
Forgejo 16.0.5 (8d24b7d) - Forgejo
Cuando [openid] ENABLE_OPENID_SIGNIN está activado, POST /user/login/openid sin autenticar entrega la URL del atacante a yohcop openid-go v1.0.1. Los helpers a nivel de paquete de esa librería usan http.DefaultClient. No hay hostmatcher en esta ruta. Los webhooks y las migraciones filtran el HTTP saliente. OpenID no lo hace.
Alguien que pueda alcanzar el formulario de inicio de sesión puede dirigir un GET de Yadis hacia loopback, RFC1918, CGNAT e IMDS desde el host de Forgejo.
| ID | sin CVE todavía |
| Clase | SSRF |
| Alcance | Remoto (sin autenticar, cuando el inicio de sesión OpenID está habilitado) |
| CWE | CWE-918 |
| CVSS | Alto: 8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Producto | Forgejo |
| Afectado | hasta v16.0.5 (8d24b7d) con ENABLE_OPENID_SIGNIN; remanente de Gitea CVE-2026-58314 |
| Auth | sin autenticar |
| Licencia | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Sin cuenta. Envía un POST con una URL de OpenID. El host de Forgejo la obtiene.
| Privilegio | Método / sink | Reconocimiento / integridad / disponibilidad | Probado en lab o inferido |
|---|---|---|---|
| Dirigir un GET de Yadis hacia loopback | POST /user/login/openid sin auth con openid=http://127.0.0.1:18080/ | Reconocimiento (HTTP saliente desde el host de Forgejo) | Probado en lab. El oráculo vio GET / con Accept: application/xrds+xml desde 127.0.0.1 |
| Sondear RFC1918, CGNAT, link-local, IMDS | Mismo http.DefaultClient Discover, sin filtro de IP | Reconocimiento | Inferido del cliente. El lab usó solo loopback |
| Repetir desde un add-OpenID con sesión iniciada | POST /user/settings/security/openid también llama a RedirectURL y omite allowedOpenIDURI | Reconocimiento | Inferido del handler. El lab usó el POST de login sin auth |
| Leer los cuerpos de respuesta en el error de login | Tras CVE-2021-45325, los errores ya no vuelcan el fetch | Reconocimiento | Probado en lab cerrado. Este remanente es la petición, no una fuga de HTML |
Cerrado en este pin: CSRF de asociación OpenID (nonce de sesión openIDState), hostmatcher de webhook/migrate (sigue usándose allí), git followRedirects=false, migrate LookupIP CVE-2026-82556. El lab no completa un inicio de sesión OpenID y no devuelve una shell.
La casilla del instalador web está activada por defecto (EnableOpenIDSignIn = MustBool(!InstallLock) mientras está desbloqueado, luego se escribe en app.ini). Tras el bloqueo, una clave omitida es false. La plantilla app.ini de Docker no tiene sección [openid], así que una imagen pre-bloqueada sin el asistente está desactivada a menos que el operador establezca la clave. Un WHITELISTED_URIS vacío permite cualquier URI.
v16.0.5 cerró el CSRF de asociación OpenID. Aun así me detuve en esa superficie. Gitea PR 38406 / CVE-2026-58314 puso un cliente filtrado por hostmatcher en una instancia dedicada de openid-go. Este pin todavía llama a los helpers a nivel de paquete.
Caminos equivocados ya registrados: volver a reportar el CSRF de asociación (ese nonce está en el árbol); tratar una imagen Docker pre-bloqueada como el valor por defecto (el asistente escribe la casilla); esperar la antigua fuga de cadena de error de OpenID; una reverse shell. Teatro.
python3 forgejo-openid-discovery-ssrf-Abraxas-Labs.py
o:
cd lab
./run.sh
Objetivo solo http://127.0.0.1:19330. Imagen codeberg.org/forgejo/forgejo:16.0.5. El oráculo comparte el netns de Forgejo y se enlaza a 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
Igual que Gitea PR 38406: un http.Client filtrado por hostmatcher en una instancia dedicada de openid-go. Mantén WHITELISTED_URIS como segunda barrera. Bloquea loopback, RFC1918, CGNAT, link-local y metadata.
modules/auth/openid/openid.goGNU Affero GPL v3.0. Ver LICENSE. Solo lab en loopback. Sin garantía.