Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-52816

CVE-2026-52816: Gogs Git Service XSS Vulnerability

CVE-2026-52816 is a Cross-Site Scripting flaw in Gogs self-hosted Git service affecting the Jupyter Notebook sanitizer endpoint. Attackers can inject malicious scripts via data URIs. This article covers affected versions, impact, and mitigation.

Published:

CVE-2026-52816 Overview

CVE-2026-52816 is a Cross-Site Scripting (XSS) vulnerability in Gogs, an open source self-hosted Git service. The flaw affects the Jupyter Notebook (ipynb) sanitizer endpoint at POST /-/api/sanitize_ipynb in all versions prior to 0.14.3. The endpoint applies bluemonday.UGCPolicy() with p.AllowURLSchemes("data"), which permits every data: URI scheme including data:text/html. Attackers can inject malicious HTML and JavaScript through crafted notebook content. The endpoint also lacks authentication middleware, so any registered user can reach it. The issue is tracked as [CWE-80] and is fixed in Gogs 0.14.3.

Critical Impact

Any authenticated Gogs user can submit notebook content that returns sanitized HTML containing attacker-controlled data:text/html payloads, enabling stored or reflected XSS against other users.

Affected Products

  • Gogs versions prior to 0.14.3
  • Self-hosted Gogs deployments exposing the /-/api/sanitize_ipynb endpoint
  • Any Gogs instance allowing user registration and notebook rendering

Discovery Timeline

  • 2026-06-24 - CVE-2026-52816 published to NVD
  • 2026-06-25 - Last updated in NVD database

Technical Details for CVE-2026-52816

Vulnerability Analysis

The Gogs sanitizer for Jupyter notebooks builds a bluemonday policy intended to render notebook output safely. The policy invokes AllowURLSchemes("data"), which whitelists the entire data: scheme without inspecting the embedded MIME type. As a result, an attacker can supply notebook content containing data:text/html;base64,... payloads that survive sanitization and execute in the victim's browser when the response is rendered.

The endpoint POST /-/api/sanitize_ipynb has no authentication middleware bound to it, so any registered account is sufficient to reach the sanitizer. Combined with the loose scheme policy, the endpoint becomes a primitive that converts user input into attacker-controlled HTML returned by the Gogs origin.

Root Cause

The root cause is improper neutralization of script-equivalent content in a web page [CWE-80]. The sanitizer relied on a coarse scheme allowlist rather than validating the MIME type carried by each data: URI. The patch replaces the broad allowlist with a per-URI policy that only accepts safe image MIME types.

Attack Vector

An attacker registers an account on a vulnerable Gogs instance, then sends a crafted ipynb payload to POST /-/api/sanitize_ipynb. The sanitizer returns HTML containing an <img> or other element whose src references data:text/html content carrying JavaScript. When a victim views the rendered notebook in their browser session, the injected script executes in the Gogs origin context, enabling session theft, CSRF chaining, and repository tampering.

go
// Patch: restrict ipynb sanitizer to safe image data URIs (#8326)
// File: internal/app/api.go

	"github.com/microcosm-cc/bluemonday"
	"gopkg.in/macaron.v1"

	"gogs.io/gogs/internal/markup"
)

func ipynbSanitizer() *bluemonday.Policy {
	p := bluemonday.UGCPolicy()
	p.AllowAttrs("class", "data-prompt-number").OnElements("div")
	p.AllowAttrs("class").OnElements("img")
-	p.AllowURLSchemes("data")
+	// Only allow data URIs with safe image MIME types to prevent XSS via
+	// "data:text/html" payloads.
+	p.AllowURLSchemeWithCustomPolicy("data", markup.IsSafeDataURI)
	return p
}

Source: GitHub Commit dd1bd98

The sanitizer helper enforces the MIME check against the URI opaque data:

go
// File: internal/markup/sanitizer.go
// IsSafeDataURI returns whether the given data URI uses a safe image MIME type.
func IsSafeDataURI(u *url.URL) bool {
	// The opaque data of a data URI has the form "mediatype;base64,data" or
	// "mediatype,data". We only allow common image MIME types.
	mediatype, _, _ := strings.Cut(u.Opaque, ";")
	// ... allowlist of image/* MIME types ...
}

Source: GitHub Commit dd1bd98

Detection Methods for CVE-2026-52816

Indicators of Compromise

  • HTTP POST requests to /-/api/sanitize_ipynb from accounts that do not normally use notebook features.
  • Sanitizer responses containing data:text/html, data:application/javascript, or other non-image data: MIME types.
  • Notebook content stored in repositories that embeds base64-encoded HTML or script payloads in src or href attributes.

Detection Strategies

  • Inspect Gogs reverse-proxy or application logs for requests to /-/api/sanitize_ipynb and correlate by user, source IP, and frequency.
  • Apply Web Application Firewall (WAF) rules that block request or response bodies containing data:(?!image/) patterns on the sanitizer endpoint.
  • Scan repositories for .ipynb files whose cell outputs contain data:text/html URIs as part of routine code-scanning pipelines.

Monitoring Recommendations

  • Alert on anomalous volumes of POST /-/api/sanitize_ipynb requests, especially from newly registered accounts.
  • Monitor browser-side Content Security Policy (CSP) violation reports referencing inline script execution on Gogs pages.
  • Track Gogs version banners across the estate to confirm upgrades to 0.14.3 or later.

How to Mitigate CVE-2026-52816

Immediate Actions Required

  • Upgrade all Gogs instances to version 0.14.3 or later, which is the official fix.
  • Disable open user registration on internet-exposed instances until the upgrade is complete.
  • Review recent notebook uploads and sanitizer requests for data:text/html payloads and remove malicious content.

Patch Information

The fix replaces p.AllowURLSchemes("data") with p.AllowURLSchemeWithCustomPolicy("data", markup.IsSafeDataURI), restricting data: URIs to safe image MIME types. Reference the GitHub Security Advisory GHSA-3w28-36p9-w929, Pull Request #8326, and Release v0.14.3 for full patch details.

Workarounds

  • Block external access to /-/api/sanitize_ipynb at the reverse proxy until the upgrade is applied.
  • Enforce a strict Content Security Policy that disallows data: URIs in script-src and restricts img-src to image/* MIME types.
  • Require authentication and rate limiting on the sanitizer endpoint via the upstream proxy where the application itself does not enforce it.
bash
# Example nginx snippet to block the sanitizer endpoint until patched
location = /-/api/sanitize_ipynb {
    return 403;
}

# Example CSP header to limit data: URI abuse
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; img-src 'self' data:; object-src 'none'" always;

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.