
Forgejo 16.0.5 - Élevée - À distance - SSRF - La découverte OpenID récupère des URL contrôlées par l'attaquant
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · forgejo-openid-discovery-ssrf
Classe : SSRF Portée : Distante
Forgejo 16.0.5 (8d24b7d) - Forgejo
Lorsque [openid] ENABLE_OPENID_SIGNIN est activé, un POST /user/login/openid non authentifié transmet l'URL de l'attaquant à yohcop openid-go v1.0.1. Les helpers au niveau du paquet de cette bibliothèque utilisent http.DefaultClient. Il n'y a pas de hostmatcher sur ce chemin. Les webhooks et les migrations filtrent le HTTP sortant. OpenID ne le fait pas.
Quiconque peut atteindre le formulaire de connexion peut déclencher un GET Yadis vers loopback, RFC1918, CGNAT et IMDS depuis l'hôte Forgejo.
| ID | pas encore de CVE |
| Classe | SSRF |
| Portée | Distante (non authentifiée, lorsque la connexion OpenID est activée) |
| CWE | CWE-918 |
| CVSS | Élevé : 8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Produit | Forgejo |
| Affecté | jusqu'à v16.0.5 (8d24b7d) avec ENABLE_OPENID_SIGNIN ; reliquat de Gitea CVE-2026-58314 |
| Auth | non authentifiée |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement |
Aucun compte. Envoyez un POST avec une URL OpenID. L'hôte Forgejo la récupère.
| Privilège | Méthode / sink | Reconnaissance / intégrité / disponibilité | Prouvé en lab ou déduit |
|---|---|---|---|
| Déclencher un GET Yadis vers loopback | POST /user/login/openid non authentifié avec openid=http://127.0.0.1:18080/ | Reconnaissance (HTTP sortant depuis l'hôte Forgejo) | Prouvé en lab. L'oracle a vu un GET / avec Accept: application/xrds+xml depuis 127.0.0.1 |
| Sonder RFC1918, CGNAT, link-local, IMDS | Même http.DefaultClient Discover, aucun filtre IP | Reconnaissance | Déduit du client. Le lab n'a utilisé que loopback |
| Répéter depuis un add-OpenID connecté | POST /user/settings/security/openid appelle aussi RedirectURL et ignore allowedOpenIDURI | Reconnaissance | Déduit du handler. Le lab a utilisé le POST de connexion non authentifié |
| Lire les corps de réponse dans l'erreur de connexion | Après CVE-2021-45325, les erreurs ne dumpent plus la récupération | Reconnaissance | Prouvé en lab comme fermé. Ce reliquat est la requête, pas une fuite HTML |
Fermé sur ce pin : CSRF d'association OpenID (nonce de session openIDState), hostmatcher webhook/migrate (toujours utilisé là), git followRedirects=false, migrate LookupIP CVE-2026-82556. Le lab ne complète pas une connexion OpenID et ne retourne pas de shell.
La case à cocher de l'installateur web est activée par défaut (EnableOpenIDSignIn = MustBool(!InstallLock) tant que non verrouillé, puis écrite dans app.ini). Après verrouillage, une clé omise est false. Le template Docker app.ini n'a pas de section [openid], donc une image pré-verrouillée sans l'assistant est désactivée sauf si l'opérateur définit la clé. Un WHITELISTED_URIS vide autorise toutes les URI.
v16.0.5 a fermé le CSRF d'association OpenID. Je suis resté sur cette surface malgré tout. Gitea PR 38406 / CVE-2026-58314 a placé un client filtré par hostmatcher dans une instance openid-go dédiée. Ce pin appelle encore les helpers au niveau du paquet.
Fausses pistes déjà enregistrées : re-signaler le CSRF d'association (ce nonce est dans l'arbre) ; traiter une image Docker pré-verrouillée comme le défaut (l'assistant active la case à cocher) ; s'attendre à l'ancienne fuite de chaîne d'erreur OpenID ; un reverse shell. Du théâtre.
python3 forgejo-openid-discovery-ssrf-Abraxas-Labs.py
ou :
cd lab
./run.sh
Cible uniquement http://127.0.0.1:19330. Image codeberg.org/forgejo/forgejo:16.0.5. L'oracle partage le netns Forgejo et se lie à 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
Identique à Gitea PR 38406 : un http.Client filtré par hostmatcher dans une instance openid-go dédiée. Conservez WHITELISTED_URIS comme second verrou. Bloquez loopback, RFC1918, CGNAT, link-local et metadata.
modules/auth/openid/openid.goGNU Affero GPL v3.0. Voir LICENSE. Lab loopback uniquement. Aucune garantie.