Skip to content
Threat Feed
critical advisory

Gitea Incomplete SSRF Protection in Webhook and Migration Allow-list

An incomplete Server-Side Request Forgery (SSRF) protection in Gitea versions prior to 1.26.3 allows authenticated users to bypass the allow-list in webhook delivery and repository migrations, enabling internal network probing and data exfiltration from sensitive services like cloud metadata endpoints.

What's new

  • l2 merged source coverage: Gitea: Cached Per-Branch Permission Check in Pre-Receive Hook Allows Full Repository Write Jul 21, 21:46 via ghsa
  • l2 merged source coverage: Gitea Fork Synchronization Bypass Exposes Private Repository Content Jul 21, 21:43 via ghsa

A critical vulnerability, CVE-2026-22874, exists in Gitea versions prior to 1.26.3, stemming from an incomplete Server-Side Request Forgery (SSRF) protection mechanism. The allow-list, MatchBuiltinExternal, used for webhook delivery and repository migrations, relies on Go's standard library net.IP.IsPrivate() function. This function's definition of "private" is too narrow, covering only RFC 1918 and RFC 4193 ranges. As a result, several commonly used internal IP ranges, such as RFC 6598 Carrier-Grade NAT (100.64.0.0/10), Azure WireServer (168.63.129.16), specific non-RFC1918 172.x.x.x ranges, and various IPv6 transition mechanisms (e.g., NAT64 64:ff9b::/96, Teredo 2001::/32), are not blocked. An authenticated user can exploit this to make Gitea initiate HTTP requests to these unblocked internal or cloud metadata endpoints and retrieve the full responses via the webhook history UI. This allows for internal network reconnaissance and sensitive data exfiltration.

Attack Chain

  1. An authenticated user gains access to a Gitea instance.
  2. The user navigates to a repository where they have permissions to create or modify a webhook, or initiate a repository migration.
  3. The user configures the webhook's target URL (or migration source URL) to point to an IP address within one of the bypassable internal ranges, such as http://168.63.129.16/metadata for Azure metadata, or http://100.64.0.1/internal_api for a Carrier-Grade NAT network.
  4. Gitea attempts to deliver the webhook or perform the migration. Its internal host matcher, MatchBuiltinExternal, uses net.IP.IsPrivate() to validate the target IP.
  5. Due to the narrow definition of IsPrivate(), the target IP is incorrectly deemed "public" and the connection is allowed.
  6. Gitea's server-side process makes an HTTP request to the specified internal resource, bypassing expected network segmentation.
  7. The internal resource responds (e.g., with cloud credentials or internal service configuration), and Gitea captures the full HTTP response, including status, headers, and up to 1 MiB of the body.
  8. The authenticated user accesses the webhook history UI for the configured webhook, which displays the captured response, effectively exfiltrating data from the internal network.

Impact

Successful exploitation of CVE-2026-22874 grants an authenticated attacker the ability to perform extensive Server-Side Request Forgery (SSRF) attacks against the internal network where the Gitea instance is hosted. This can lead to the compromise of sensitive internal systems and data. Specific impacts include accessing cloud metadata endpoints (e.g., AWS IMDS via NAT64, Azure WireServer), probing and exfiltrating data from internal services operating on Carrier-Grade NAT (100.64.0.0/10) or non-RFC1918 172.x.x.x ranges. The non-blind nature of the SSRF means attackers can read full HTTP response bodies through the webhook history UI, allowing for reconnaissance, sensitive information disclosure, and potential privilege escalation by acquiring credentials or API keys.

Recommendation

  • Upgrade Gitea to version 1.26.3 or later immediately to address CVE-2026-22874.
  • Review your Gitea server's outbound network connections for anomalous activity to the IP ranges listed in the IOC table, particularly to cloud metadata service IP addresses.
  • Implement network egress filtering on the Gitea server to restrict outbound connections to only necessary and explicitly allowed external destinations, blocking all communication to the internal and cloud metadata IP ranges mentioned in this brief.

Indicators of compromise

1

ip

TypeValue
ip168.63.129.16