Gogs CVE-2026-52798
HIGHSeverity by source
AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:L
Network-reachable web UI (AV:N), trivial crafted file (AC:L), attacker needs a normal account to push (PR:L), victim must click the link (UI:R), XSS escapes notebook context to whole Gogs origin (S:C) with high C/I and some availability impact via admin actions.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:L
Lifecycle Timeline
3DescriptionGitHub Advisory
Summary
Although .ipynb previews are sanitized on the server side via /-/api/sanitize_ipynb, the inserted content is re-rendered on the client side without sanitization using marked() on elements with the .nb-markdown-cell class. During this process, links containing schemes such as javascript: can be regenerated.
As a result, when a victim views an attacker-crafted .ipynb file and clicks the link, arbitrary JavaScript is executed in the Gogs origin, leading to a click-based Stored XSS.
Details
After the rendered output of a .ipynb file is sanitized via /-/api/sanitize_ipynb and inserted into the DOM, only the Markdown cell portions are re-rendered using marked() and overwritten in the DOM. During this process, links with the javascript: scheme can be regenerated.
templates/repo/view_file.tmpl:42-71
{{else if .IsIPythonNotebook}}
<script>
$.getJSON("{{.RawFileLink}}", null, function(notebook_json) {
var notebook = nb.parse(notebook_json);
var rendered = notebook.render();
$.ajax({
type: "POST",
url: '{{AppSubURL}}/-/api/sanitize_ipynb',
data: rendered.outerHTML,
processData: false,
contentType: false,
}).done(function(data) {
$("#ipython-notebook").append(data);
$("#ipython-notebook code").each(function(i, block) {
$(block).addClass("py").addClass("python");
hljs.highlightBlock(block);
});
// Overwrite image method to append proper prefix to the source URL
var renderer = new marked.Renderer();
var context = '{{.RawFileLink}}';
context = context.substring(0, context.lastIndexOf("/"));
renderer.image = function (href, title, text) {
return `<img src="${context}/${href}"`
};
$("#ipython-notebook .nb-markdown-cell").each(function(i, markdown) {
$(markdown).html(marked($(markdown).html(), {renderer: renderer}));
});
});
});
</script>While regular HTML pages (including .ipynb preview pages) are served without a Content Security Policy (CSP), CSP headers are applied only to attachment delivery routes.
internal/cmd/web.go:323
c.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox")Steps to Reproduce
- As the attacker, add and push/commit a
.ipynbfile containing ajavascript:link in a Markdown cell to a repository.
- Example (PoC):
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[poc](javascript:alert(document.domain))"
]
}
]
}- The victim opens the file on Gogs (e.g.,
/<user>/<repo>/src/<branch>/poc.ipynb).
<img width="2386" height="1218" alt="image" src="https://github.com/user-attachments/assets/b0d93fd8-c5ca-4058-8af0-98dee590d3ad" />
- When the victim clicks the
poclink displayed in the preview,alert(document.domain)is executed in the same Gogs origin.
<img width="2390" height="1388" alt="image" src="https://github.com/user-attachments/assets/0eb6ebe8-632c-4a41-8a11-46471514b4c4" />
Minimum Required Privileges
- Attacker: Ability to place a
.ipynbfile as a regular (non-admin) user - For example: a general user who can create a public repository and add files.
- Or: write access (collaborator, etc.) to an existing repository that the victim will view.
- Victim: Permission to view the repository (a click is required).
Impact
- Unauthorized actions performed with the victim’s account privileges (e.g., repository settings changes, Issue operations,誘導 to token creation).
- Theft of information accessible to the victim (repository/Issue/Wiki contents, tokens exposed in page context).
- If the victim is an administrator, the impact may escalate to instance-wide configuration changes and user management.
Articles & Coverage 1
AnalysisAI
Stored cross-site scripting in Gogs (self-hosted Git service) versions through 0.14.2 allows a low-privileged repository user to inject JavaScript via a crafted Jupyter notebook (.ipynb) Markdown cell containing a javascript: scheme link, which executes in the Gogs origin when a victim clicks the rendered link. Although server-side sanitization is performed via /-/api/sanitize_ipynb, the client subsequently re-renders Markdown cells with marked() and regenerates the dangerous links, and the file preview page is served without a Content Security Policy. …
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 | Attacker must hold a low-privileged authenticated Gogs account with permission to commit a .ipynb file to a repository the victim will browse - either by creating their own public repo or by being a collaborator on an existing repo. … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | The CVSS 3.1 vector (AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:L, score 8.9) reflects a network-reachable, low-complexity attack that requires authenticated push access plus a victim click but achieves scope change with high confidentiality and integrity impact - consistent with a Stored XSS in an authenticated SaaS-style web UI. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | An attacker with normal user privileges creates a public repository (or commits to a repo where they are a collaborator) and pushes a .ipynb file whose Markdown cell contains [poc](javascript:alert(document.domain)) - the exact PoC published in the advisory. They then send the repository link to a targeted Gogs user, ideally an administrator; when the victim opens the notebook preview and clicks the link, attacker-controlled JavaScript runs in the Gogs origin and can exfiltrate the victim's session, create personal access tokens, or pivot to instance-wide configuration changes if the victim is an admin. |
| Remediation | Vendor-released patch: upgrade Gogs to version 0.14.3 or later as published at https://github.com/gogs/gogs/releases/tag/v0.14.3, which applies the fix from PR #8319 (commit 17b168b11ca759a7550e1f4bbd68bbde14db7785) and removes the bundled marked-0.8.1 client renderer that regenerated javascript: links. … Detailed patch versions, workarounds, and compensating controls in full report. |
Recommended ActionAI
Within 24 hours: Identify all Gogs deployments and determine which run version 0.14.2 or earlier. …
Sign in for detailed remediation steps and compensating controls.
Threat intelligence, references, and detailed analysis are available after sign-in.
More from same product – last 7 days
Authentication bypass in StarTree mcp-pinot versions 3.0.1 and earlier exposes the Model Context Protocol HTTP server on
Unauthenticated remote code execution in IBM Langflow OSS versions 1.0.0 through 1.9.3 allows attackers to fully comprom
Cross-user flow execution in Langflow versions prior to 1.9.1 allows any authenticated API user to run another user's fl
Unauthenticated remote code execution in Crawl4AI versions <= 0.8.6 allows attackers to escape the AST-based sandbox in
InHand Networks IR912 V1.0.0.r20042 and IR915 V1.0.0.r20042 (including earlier versions) were discovered to contain a co
Share
External POC / Exploit Code
Leaving vuln.today
GHSA-jq8v-rmf6-65jw