
CVE-2026-22874 Analyse: unvollständige SSRF-Whitelist im Gitea-Webhook/Migration (IPv6-Übergang und Cloud-Metadaten). Behoben in Gitea 1.26.3.
Technische Beschreibung und Referenzen für CVE-2026-22874 (GHSA-2r5c-gw76-rh3w): eine unvollständige SSRF-Allowlist in Giteas Webhook-Zustellung und Repository-Migration, behoben in Gitea 1.26.3.
Ich habe diese SSRF-Klasse unabhängig den Gitea-Maintainern gemeldet und werde als Mitwirkender (other) im veröffentlichten Advisory genannt; der Hauptmelder des Advisories ist J. Leitschuh. Dieses Repository ist eine defensive, lehrreiche Aufarbeitung des öffentlichen Advisories – das Problem ist behoben.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N)<= 1.26.2 — Behoben: 1.26.3Giteas standardmäßige SSRF-Allowlist (MatchBuiltinExternal, verwendet sowohl für Webhook-Zustellung als auch für Repository-Migrationen) stützte sich auf die Go-Standardbibliothek , die nur RFC 1918 (, , ) und RFC 4193 () erkennt. Mehrere Adressbereiche, die üblicherweise für Cloud-Metadaten-Dienste, interne Netzwerke und IPv6-Übergangsmechanismen verwendet werden, gelten gemäß dieser Definition nicht als „privat“ und passierten daher den „externen“ Filter, sodass ein authentifizierter Benutzer den Server HTTP-Anfragen an diese Ziele stellen lassen konnte.
net.IP.IsPrivate()10/8172.16/12192.168/16fc00::/7Da die Webhook-Zustellung den Antwortstatus, Header und bis zu ~1 MiB des Body aufzeichnet und in der Webhook-Verlaufsoberfläche anzeigt, ist der SSRF nicht blind: Der Angreifer kann lesen, was der anvisierte interne Dienst zurückgibt.
net.IP.IsPrivate() übersehene Bereiche| Bereich | Bedeutung |
|---|---|
100.64.0.0/10 | RFC 6598 Carrier-Grade NAT |
168.63.129.16/32 | Azure WireServer / Instance-Metadata-Endpunkt |
64:ff9b::/96 | RFC 6052 NAT64 (kann 169.254.169.254 einbetten, z. B. AWS IMDS) |
2001::/32 | RFC 4380 Teredo |
2002::/16 | RFC 3056 6to4 |
IPv4-zu-IPv6-gemappte Formen der obigen Bereiche sind in gleicher Weise betroffen.
Ein authentifizierter Benutzer, der einen Webhook erstellen oder ändern (oder eine Migration starten) kann, kann daher Cloud-Metadaten-Endpunkte erreichen – zum Beispiel AWS IMDS über eine NAT64-Abbildung oder den Azure WireServer unter 168.63.129.16 – sowie ausschließlich interne Dienste und dann die Antwort über die Webhook-Verlaufsansicht auslesen.
Die Standardrichtlinie ist MatchBuiltinExternal in Giteas HostMatchList-Prüfung, die jede global-unicast-, nicht-IsPrivate()-Adresse als erlaubt behandelte:
case MatchBuiltinExternal:
if ip.IsGlobalUnicast() && !ip.IsPrivate() {
return true
}
net.IP.IsPrivate() ist keine Sicherheitsgrenze für „extern“: Es berücksichtigt weder Carrier-Grade NAT, Cloud-Metadaten-Endpunkte noch IPv6-Übergangsbereiche, die zu internen oder Metadaten-Zielen geroutet werden können.
Behoben in Gitea 1.26.3 durch Erweiterung des eingebauten Filters, um die oben genannten zusätzlichen Bereiche zu blockieren. Betreiber sollten auf 1.26.3 oder später aktualisieren. Als Defense-in-Depth: