Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Network endpoint requiring a registered account (PR:L) and victim browser interaction (UI:R) for stored XSS; scope changes as JavaScript executes in victim's browser session (S:C), with low confidentiality and integrity impact.
Primary rating from Vendor (https://github.com/gogs/gogs).
CVSS VectorVendor: https://github.com/gogs/gogs
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Lifecycle Timeline
3DescriptionCVE.org
Summary
The Jupyter Notebook (ipynb) sanitizer endpoint at POST /-/api/sanitize_ipynb allows arbitrary data: URIs without proper restrictions, potentially leading to Cross-Site Scripting (XSS). The endpoint uses bluemonday.UGCPolicy() with p.AllowURLSchemes("data") which permits all data URI schemes including data:text/html, enabling attackers to inject malicious HTML/JavaScript. Additionally, the endpoint has no authentication middleware, allowing any registered user to exploit this vulnerability.
Severity
High
Affected Versions
All versions using the vulnerable endpoint
Vulnerability Details
- CVE ID: (To be assigned)
- Entry Point:
POST /-/api/sanitize_ipynb - Attack Vector: Network
- Authentication Required: No (only needs a registered user account)
Impact
An attacker with a registered user account can:
- Send malicious HTML containing
data:text/htmlURIs to the sanitization endpoint - Receive sanitized but attacker-controlled HTML in the response
- Execute arbitrary JavaScript in the attacker's browser context through XSS
- Potentially exploit other users if the sanitized output is rendered in their context
The vulnerability has higher severity because:
- No authentication required (only needs a registered user account)
- Unlike the safer pattern in
internal/markup/sanitizer.go:39which usesisSafeDataURIto only allow safe image MIME types, this endpoint allows ALL data URIs including HTML - The returned HTML can be used to craft XSS attacks
Proof of Concept
Attacker sends a POST request to the sanitization endpoint:
POST /-/api/sanitize_ipynb HTTP/1.1
Host: target.gogs.instance
Content-Type: text/plain
<a href="data:text/html,<script>alert(document.cookie)</script>">click</a>The server returns the sanitized HTML with the data URI preserved:
<a href="data:text/html,<script>alert(document.cookie)</script>">click</a>When this HTML is rendered in a browser, the JavaScript within the data URI will execute, leading to XSS.
Affected Component
File: internal/app/api.go:10-16
func ipynbSanitizer() *bluemonday.Policy {
p := bluemonday.UGCPolicy()
p.AllowAttrs("class", "data-prompt-number").OnElements("div")
p.AllowAttrs("class").OnElements("img")
p.AllowURLSchemes("data") // <-- VULNERABLE: allows all data URIs
return p
}File: cmd/gogs/web.go:681-683 - No authentication middleware
m.Group("/-", func() {
m.Get("/metrics", app.MetricsFilter(), promhttp.Handler())
m.Group("/api", func() {
m.Post("/sanitize_ipynb", app.SanitizeIpynb()) // <-- No auth middleware
})
})Root Cause
- Unrestricted data URI scheme: The code at
internal/app/api.go:14usesp.AllowURLSchemes("data")without any restriction, unlike the safer implementation ininternal/markup/sanitizer.go:39which usesAllowURLSchemeWithCustomPolicy("data", isSafeDataURI)to only allow safe image MIME types. - No authentication: The endpoint at
cmd/gogs/web.go:682does not have any authentication middleware applied, making it accessible to any registered user. - Insufficient validation: The sanitization only removes dangerous tags/attributes but preserves data URIs, allowing
data:text/htmlpayloads to pass through.
Suggested Fix
Option 1: Use the same safe pattern as internal/markup/sanitizer.go
Replace p.AllowURLSchemes("data") with:
p.AllowURLSchemeWithCustomPolicy("data", isSafeDataURI)Where isSafeDataURI is a function that only allows safe image MIME types (image/png, image/jpeg, image/gif, etc.).
Option 2: Add authentication middleware
Apply appropriate authentication to the endpoint:
m.Post("/sanitize_ipynb", middleware.signIn, app.SanitizeIpynb())Option 3: Disable data URI scheme entirely
If data URIs are not required for ipynb sanitization:
// Remove this line entirely:
// p.AllowURLSchemes("data")AnalysisAI
Stored XSS in Gogs's Jupyter notebook (.ipynb) preview allows any registered user to inject arbitrary JavaScript via data:text/html URIs that survive the bluemonday sanitization pipeline, affecting all versions prior to 0.14.3. The POST /-/api/sanitize_ipynb endpoint uses p.AllowURLSchemes("data") without MIME-type gating, unlike the safer IsSafeDataURI validator used elsewhere in the codebase, and carries no authentication middleware - making it reachable by any account holder. …
Unlock full vulnerability intelligence
- Risk assessment & exploitation conditions
- Attack chain visualization
- Remediation with exact patch versions
- Threat intelligence from 22 sources
- Personal watchlist & email alerts
Free forever · No credit card required
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata
Vulnerability AssessmentAI
| Exploitation | The attacker must possess a registered Gogs user account - anonymous access is not sufficient, though the `/-/api/sanitize_ipynb` endpoint itself applies no explicit authentication middleware at the routing layer. … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | No vendor-supplied CVSS vector or EPSS score is available for CVE-2026-52816, so quantitative risk signals are absent. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | A registered user on a public Gogs instance sends a POST request to `/-/api/sanitize_ipynb` containing `<a href="data:text/html,<script>alert(document.cookie)</script>">click</a>`; the server returns the payload intact because bluemonday's policy allows all data URI schemes. The attacker embeds this sanitized output into a shared Jupyter notebook in a repository, and when another authenticated user opens the notebook preview, the `data:text/html` URI resolves in their browser and the embedded script executes, exposing their session cookie. … |
| Remediation | Upgrade Gogs to version 0.14.3 or later; this release replaces the unsafe `p.AllowURLSchemes("data")` call in `internal/app/api.go` with `p.AllowURLSchemeWithCustomPolicy("data", markup.IsSafeDataURI)`, restricting data URIs to safe image MIME types. … Detailed patch versions, workarounds, and compensating controls in full report. |
Threat intelligence, references, and detailed analysis are available after sign-in.
Same weakness CWE-79 – Cross-site Scripting (XSS)
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-39076
GHSA-3w28-36p9-w929