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.
// 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:
// 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.
# 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.

