CVE-2026-96594
Executive Summary
CVE-2026-96594 is a stored cross-site scripting (XSS) vulnerability in the Gitea API media endpoint GET /api/v1/repos/{owner}/{repo}/media/{filepath}, which returns small (up to 1 KiB) Git-stored files without applying the content type and disposition headers Gitea normally uses for user-supplied content. As a result, an HTML file committed to a repository is rendered by the victim's browser on the Gitea origin instead of being displayed as inert text or downloaded. Any user with push access to a repository can execute JavaScript in the session of a victim who opens the crafted media URL, allowing the attacker to act with the victim's permissions. No CVSS score, EPSS score, PoC, or vendor patch currently exists in the referenced data sources.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability resides in the response-handling logic of the Gitea API endpoint that serves repository media objects. According to the NVD description, GET /api/v1/repos/{owner}/{repo}/media/{filepath} retrieves files of up to 1 KiB that are stored directly in Git (not through Git LFS) and writes them to the HTTP response "without the content type and disposition headers Gitea uses for user content."
The root cause is a missing HTTP response header hardening control. When Gitea serves user-controlled repository content in a web-adjacent context, it ordinarily sets a restrictive Content-Type (e.g., forcing a non-renderable type) and a Content-Disposition header (e.g., attachment) — the exact header values are not specified in the available description, but the vulnerability class is clear from the behavior described. Because these headers are omitted on this endpoint, a browser processing the response performs content sniffing or honors the file's intrinsic HTML nature and renders it as an active document. The response originates from the Gitea origin, so the rendered document executes in the security context of the Gitea application.
This is a classic stored XSS (CWE-79) driven by missing output/serving controls rather than by unsanitized input echoing. The attack surface is the HTTP API media retrieval path. The 1 KiB size limit constrains payload size but is more than sufficient for a compact HTML/JavaScript payload that steals session tokens, performs authenticated actions via the victim's cookies, or injects a persistent DOM hook.
No source code, commit, or patch is referenced in the available data, so specific implementation details such as the exact header assignments, sanitization routines, or the code path that omits them cannot be derived and are not asserted here. Key facts that are established: the endpoint path, the file size ceiling, the storage mechanism (Git, not LFS), the missing headers, the browser-render outcome, and the permission required (push access).
Exploitation Scenarios
No public proof-of-concept exists; the following chain is inferred strictly from the vulnerability class and the facts stated in the NVD description.
Reconnaissance / target identification. The attacker identifies a reachable Gitea instance and obtains push access to at least one repository (e.g., as a legitimate contributor, a compromised low-privilege account, or via any other means of obtaining write access). The attacker confirms the existence of the media endpoint
GET /api/v1/repos/{owner}/{repo}/media/{filepath}and that it serves small Git-stored files.Triggering the flaw class. The attacker commits an HTML file of up to 1 KiB directly into the repository's Git storage (not LFS). Because the media endpoint writes the file to the response without the content type and disposition headers used for user content, the browser is free to interpret the file as an HTML document rather than as inert output.
Payload / execution method. The attacker hosts the file at the predictable media URL and delivers that URL to a victim (for example, a maintainer or administrator) via chat, email, issue comments, or any link-sharing channel. When the victim opens the URL, the browser renders the committed HTML on the Gitea origin and executes the embedded JavaScript. At the vulnerability-class level, the payload is an XSS script — commonly used to read session data available to JavaScript, issue same-origin requests, or rewrite page content — but the description does not specify a particular payload, and none is fabricated here.
Post-exploitation impact. The script runs with the victim's permissions and on the Gitea origin. The attacker can act within the victim's session: performing authenticated actions on the victim's behalf, accessing private repositories and metadata visible to the victim, and exfiltrating any data reachable through the browser session. Because the malicious file is committed to a repository, the link persists and can be re-shared, giving the attack a stored, repeatable character.
Constraints worth noting: exploitation requires the attacker to have push access (a non-trivial precondition captured by the low-privilege requirement), the victim must click the crafted URL (user interaction), and the file must remain within the 1 KiB ceiling.
Impact Assessment
- Confidentiality: Limited-to-moderate. Script execution in the victim's session can expose data the victim can view, including private repository content and API-accessible resources. Scope change (S:C) reflects that the injection can affect resources beyond the vulnerable component boundary, e.g., the victim's session context.
- Integrity: Limited. The attacker can perform actions as the victim and alter rendered content.
- Availability: No direct availability impact.
- Blast radius: Any Gitea deployment exposing the affected media endpoint. The initial compromise is repository-scoped, but the true blast radius is determined by the privileges of the victim who opens the URL — an administrator victim elevates the impact substantially.
- CVSS/scoring status: No CVSS score or vector is provided by the source data (NVD reports N/A). No EPSS score exists. The vector shown in METADATA is an analyst-constructed representation of the described attack, not an official score.
- Exploitability context: No public PoC, no Nuclei template, no known exploitation in the wild, and not listed in CISA KEV. The precondition of push access and the need for victim interaction reduce immediate mass-exploitation risk relative to unauthenticated bugs, but insider, contributor, and supply-chain abuse remain realistic vectors.
Detection Guidance
Sigma Rule
title: Potential Gitea Media Endpoint XSS Access (CVE-2026-96594)
id: 3f9c1d2a-8b74-4e0c-9a5e-gitea96594
status: experimental
description: Detects HTTP requests to the Gitea repository media endpoint that may host an HTML file used for stored XSS via CVE-2026-96594.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-96594
author: valtersit.com Threat Intelligence
date: 2026-01-01
logsource:
category: webserver
detection:
selection_method:
cs-method: 'GET'
selection_uri:
cs-uri-stem|contains: '/api/v1/repos/'
cs-uri-stem|contains: '/media/'
selection_ext:
cs-uri-stem|endswith:
- '.html'
- '.htm'
- '.svg'
condition: selection_method and selection_uri and selection_ext
falsepositives:
- Legitimate repository access to HTML/HTM/SVG media files by authenticated users
level: medium
tags:
- attack.t1189
- cwe.79
YARA Rule
rule CVE_2026_96594_Gitea_Media_XSS_HTML
{
meta:
description = "Detects small HTML files committed to repositories that could be served via the Gitea media endpoint and rendered (CVE-2026-96594)"
author = "valtersit.com Threat Intelligence"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-96594"
date = "2026-01-01"
severity = "medium"
strings:
$html1 = "<html" nocase
$html2 = "<!DOCTYPE html" nocase
$script1 = "<script" nocase
$script2 = "</script>" nocase
$body = "<body" nocase
condition:
filesize < 1KB and
(any of ($html1, $html2)) and
any of ($script1, $script2, $body)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-96594 Gitea Media Endpoint XSS Access Attempt"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"/api/v1/repos/"; http.uri; content:"/media/"; pcre:"/\/media\/[^\s]*(\.html|\.htm|\.svg)(\?|$)/Ui"; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-96594; classtype:web-application-attack; sid:9659401; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=5m
[ network where http.request.method == "GET"
and http.request.uri : "/api/v1/repos/*/media/*"
and http.request.uri : ("*.html*" or "*.htm*" or "*.svg*")]
Splunk SPL Query
index=web OR index=proxy
| search (uri_path="/api/v1/repos/*/media/*" OR cs_uri_stem="/api/v1/repos/*/media/*")
| regex uri_path="(?i)/media/[^\s]+\.(html|htm|svg)(\?|$)"
| stats count min(_time) as first_seen max(_time) as last_seen values(status) as status_codes by src_ip, uri_path, user_agent
| sort - count
| table first_seen, last_seen, src_ip, uri_path, status_codes, user_agent, count
Wazuh OSSEC Rule
<group name="web,gitea,cve-2026-96594,">
<rule id="965940" level="6">
<if_sid>31100</if_sid>
<id>^GET$</id>
<url>/api/v1/repos/</url>
<url>/media/</url>
<description>Gitea media endpoint accessed - possible CVE-2026-96594 stored XSS vector</description>
<mitre>
<id>T1189</id>
</mitre>
<group>cve_2026_96594,xss,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). No vendor fix, workaround, affected version range, OSV package data, or commit reference is available in the provided intelligence. The following guidance is preventive and defense-oriented.
Immediate mitigations (no vendor patch available):
- Restrict who can push to repositories to trusted, vetted contributors; this directly removes the precondition required to plant the malicious file.
- Treat links to the media endpoint
GET /api/v1/repos/{owner}/{repo}/media/{filepath}as untrusted; avoid opening them while authenticated as an administrative user. - Front the Gitea instance with a reverse proxy or WAF that forces a restrictive
Content-Type(or anattachmentdisposition) on responses from the/api/v1/repos/*/media/*path, and that neutralizes HTML/SVG content types on this route. - Disable or block the affected media path in the proxy/WAF until a fix is applied, if operational constraints permit.
- Reduce the value of XSS on the Gitea origin: enable a strong Content-Security-Policy (via the proxy if Gitea does not expose it natively) and set session cookies with
HttpOnlyandSameSiteattributes so script access to session material is limited.
Patch / upgrade steps:
- Monitor the Gitea project's security advisories and release notes for a fix referencing CVE-2026-96594; no fixed version is known at this time.
- Once a patched release is published, validate it in staging (confirm the media endpoint now returns the hardened content type and disposition headers for Git-stored files), then upgrade promptly.
- Subscribe to the project's release and security feeds and re-run this assessment when patch telemetry becomes available.
Long-term hardening:
- Adopt a secure-content-serving baseline for all endpoints that return user-controlled data: explicit
Content-Type,Content-Disposition: attachmentwhere rendering is not intended,X-Content-Type-Options: nosniff, and a strict CSP. - Enforce least privilege on repository write access and review contribution paths (including CI and bot accounts) that could commit malicious files.
- Log and review access to media/API endpoints and alert on outbound links to untrusted repository content.
- Maintain an SBOM and vulnerability-tracking process so that patch availability is detected and triaged automatically.
- Adopt a secure-content-serving baseline for all endpoints that return user-controlled data: explicit
References
- NVD — CVE-2026-96594: https://nvd.nist.gov/vuln/detail/CVE-2026-96594
- Gitea project (vendor) — monitor official security advisories and release notes: https://github.com/go-gitea/gitea
- MITRE CWE-79 — Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'): https://cwe.mitre.org/data/definitions/79.html
- MITRE ATT&CK T1189 — Drive-by Compromise: https://attack.mitre.org/techniques/T1189/
- FIRST EPSS — no score available for CVE-2026-96594 at time of writing; consult https://www.first.org/epss/ for future updates
No threat actor campaigns, exploit-in-the-wild evidence, or CISA KEV listing is associated with CVE-2026-96594 in the available data. No public PoC or Nuclei template exists. All exploit and detection content above is derived from the vulnerability class and the details stated in the NVD description.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.