CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-xmj7-xj85-hfc3: Gitea: SSRF in restore-repo via unsanitized pull_request.yml Head.CloneURL

mediumCVSS 6.3CVE-2026-58441
Summary Gitea's restore-repo CLI command restores a repository from a dump directory/archive. When parsing pull_request.yml from that dump, the Head.CloneURL field is used to add a git remote and fetch from it with no validation, because the safety check that's supposed to guard it (CheckAndEnsureSafePR) is called with an empty commonCloneBaseURL, which silently disables it. This lets a malicious dump make the Gitea server execute git fetch against an attacker-chosen URL (SSRF), or disclose a local git repository via file://. This is a different root cause from the recently fixed path-traversal issue in the same command (#38215), which patched DownloadURL/PatchURL but not Head.CloneURL. Details services/migrations/restore.go's GetPullRequests() unmarshals pull_request.yml directly into base.PullRequest structs with no validation of Head.CloneURL: err = yaml.Unmarshal(bs, &pulls) ... for _, pr := range pulls { if pr.PatchURL != "" { pr.PatchURL = "file://" + util.FilePathJoinAbs(r.baseDir, pr.PatchURL) } CheckAndEnsureSafePR(pr, "", r) // <-- empty baseURL } CheckAndEnsureSafePR (services/migrations/common.go) is supposed to reject Head.CloneURL/PatchURL values that don't share a common base URL: func hasBaseURL(toCheck, baseURL string) bool { if len(baseURL) > 0 && baseURL[len(baseURL)-1] != '/' { baseURL += "/" } return strings.HasPrefix(toCheck, baseURL) } func CheckAndEnsureSafePR(pr *base.PullRequest, commonCloneBaseURL string, g base.Downloader) bool { valid := true if pr.PatchURL != "" && !hasBaseURL(pr.PatchURL, commonCloneBaseURL) { pr.PatchURL = "" valid = false } if pr.Head.CloneURL != "" && !hasBaseURL(pr.Head.CloneURL, commonCloneBaseURL) { pr.Head.CloneURL = "" valid = false } return valid } strings.HasPrefix(anything, "") is always true in Go. Because restore.go is the only caller that passes "" as commonCloneBaseURL, this check is a complete no-op on the restore-repo path — Head.CloneURL survives unchanged regardless of its value. Every other do

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
medium — CVSS 6.3
Published
2026-07-21
Last updated
2026-07-21
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-xmj7-xj85-hfc3

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-58441coverage & exploitation statusNVD · CVE.org

Same CVEs, other sources

How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.

More from GitHub Security Advisories