
Analisi di CVE-2026-22874: lista di permessi SSRF incompleta nei webhook/migration di Gitea (transizione IPv6 e metadati cloud). Risolto in Gitea 1.26.3.
Descrizione tecnica e riferimenti per CVE-2026-22874 (GHSA-2r5c-gw76-rh3w): una lista di permessi SSRF incompleta nella consegna dei webhook e nella migrazione dei repository di Gitea, corretta in Gitea 1.26.3.
Ho segnalato indipendentemente questa classe di SSRF ai manutentori di Gitea e sono accreditato come contributore (other) nell'avviso pubblicato; il segnalatore principale dell'avviso è J. Leitschuh. Questo repository è una descrizione difensiva ed educativa dell'avviso pubblico — il problema è risolto.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N)<= 1.26.2 — Corretta in: 1.26.3La lista di permessi SSRF predefinita di Gitea (, utilizzata sia per la consegna dei webhook che per le migrazioni dei repository) si basava sulla funzione della libreria standard di Go, che riconosce solo RFC 1918 (, , ) e RFC 4193 (). Diversi intervalli di indirizzi comunemente utilizzati per servizi di metadati cloud, reti interne e meccanismi di transizione IPv6 non sono "privati" secondo quella definizione e quindi superavano il filtro "esterno", permettendo a un utente autenticato di far inviare richieste HTTP dal server a quelle destinazioni.
MatchBuiltinExternalnet.IP.IsPrivate()10/8172.16/12192.168/16fc00::/7Poiché la consegna del webhook registra lo stato della risposta, le intestazioni e fino a ~1 MiB di corpo e lo visualizza nell'interfaccia della cronologia dei webhook, l'SSRF non è cieco: l'attaccante può leggere ciò che il servizio interno bersaglio restituisce.
net.IP.IsPrivate()| Intervallo | Significato |
|---|---|
100.64.0.0/10 | RFC 6598 NAT per operatore |
168.63.129.16/32 | Azure WireServer / endpoint metadati istanza |
64:ff9b::/96 | RFC 6052 NAT64 (può incorporare 169.254.169.254, es. AWS IMDS) |
2001::/32 | RFC 4380 Teredo |
2002::/16 | RFC 3056 6to4 |
Le forme IPv6 mappate IPv4 degli intervalli sopra sono influenzate allo stesso modo.
Un utente autenticato che può creare o modificare un webhook (o avviare una migrazione) può quindi raggiungere gli endpoint dei metadati cloud — ad esempio AWS IMDS tramite un mapping NAT64, o Azure WireServer a 168.63.129.16 — e servizi solo interni, quindi leggere la risposta attraverso la vista della cronologia dei webhook.
La policy predefinita è MatchBuiltinExternal nel controllo HostMatchList di Gitea, che considerava consentito qualsiasi indirizzo unicast globale non IsPrivate():
case MatchBuiltinExternal:
if ip.IsGlobalUnicast() && !ip.IsPrivate() {
return true
}
net.IP.IsPrivate() non è un confine di sicurezza per "esterno": non tiene conto del NAT per operatore, degli endpoint dei metadati cloud o degli intervalli di transizione IPv6 che possono essere instradati verso destinazioni interne o di metadati.
Corretto in Gitea 1.26.3 estendendo il filtro integrato per bloccare gli intervalli aggiuntivi sopra. Gli operatori dovrebbero aggiornare a 1.26.3 o successivo. Come difesa in profondità: