CVE-2026-52808: Gogs.io/gogs Gogs's Write-level Collaborators Can Mutate Vulnerability

HIGH
Advisory Identifier: GHSA-268j-37xf-pp52
CVSS 7.1
CWE-269 CWE-863
Published
Advisory Summary

CVE-2026-52808 is a HIGH (CVSS 7.1) gogs's write-level collaborators can mutate vulnerability (CWE-269: Improper Privilege Management) affecting Gogs.io/gogs libraries in the Go ecosystem. The issue involves gogs's write-level collaborators can mutate admin-only repository settings via api. Remediation is available by upgrading affected packages to version 0.14.3.

CVE-2026-52808 at a Glance

CVE Identifier CVE-2026-52808
GHSA Identifier GHSA-268j-37xf-pp52
Severity HIGH
CVSS v3.1 Base Score 7.1
CWE Classification CWE-269: Improper Privilege Management
Affected Product Gogs.io/gogs
Package Ecosystem Go
Published Date
Last Updated

Security Impact

CVSS: 7.1

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity High (I:H)
Availability Low (A:L)

How to Fix CVE-2026-52808

To remediate this vulnerability, upgrade all affected Gogs.io/gogs dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

gogs.io/gogs fixed: 0.14.3
Upgrade gogs.io/gogs to 0.14.3
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for gogs.io/gogs

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-52808, inspect your project dependencies for Gogs.io/gogs:

inspect dependencies for gogs.io/gogs

Analyze the terminal output to locate any version of Gogs.io/gogs in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.14.3), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-269: Improper Privilege Management, where the product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor. In Gogs.io/gogs, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary Three 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 gated by `reqRepoWriter()` rather than `reqRepoAdmin()`. The equivalent operations in the web UI sit behind `reqRepoAdmin`, which requires `AccessMode >= AccessModeAdmin`. A write-level collaborator (who has `AccessMode == AccessModeWrite < AccessModeAdmin`) can therefore call these API endpoints directly to disable the native issue tracker or wiki, inject attacker-controlled external tracker/wiki URLs that redirect all repository visitors, or trigger mirror sync — none of which they are authorized to do. ## Severity **High** (CVSS 3.1: 7.1) `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L` - **Attack Vector:** Network — the API endpoints are reachable over HTTP/S. - **Attack Complexity:** Low — a single API call is sufficient; no chaining or race condition required. - **Privileges Required:** Low — only write-level collaborator access to the targeted repository is needed. The attacker does not need repo-admin or site-admin privileges. - **User Interaction:** None — the attacker acts unilaterally. - **Scope:** Unchanged — the impact is contained to the targeted repository's settings and its visitors. - **Confidentiality Impact:** None — the attacker does not read confidential data directly. - **Integrity Impact:** High — the attacker permanently mutates repository configuration, including injecting an external URL that redirects all visitors who click the Issues or Wiki tabs to an attacker-controlled site. - **Availability Impact:** Low — disabling the native issue tracker or wiki reduces the availability of those features for all repository participants. ## Affected component - `internal/route/api/v1/api.go` — route registration (lines 365–367) - `internal/route/api/v1/repo_repo.go` — `issueTracker()` (line 400), `wiki()` (line 437), `mirrorSync()` (line 463) ## CWE - **CWE-863**: Incorrect Authorization - **CWE-269**: Improper Privilege Management ## Description ### Three admin-equivalent API endpoints are protected by write-level middleware `api.go:365-367` registers the three settings endpoints with `reqRepoWriter()`: ```go // 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) ``` `reqRepoWriter()` (defined at `api.go:131-138`) passes any user whose repository `AccessMode >= AccessModeWrite`: ```go func reqRepoWriter() macaron.Handler { return func(c *context.Context) { if !c.Repo.IsWriter() { c.Status(http.StatusForbidden) return } } } ``` The handlers themselves perform no additional privilege check before mutating state: ```go // internal/route/api/v1/repo_repo.go:400-428 func issueTracker(c *context.APIContext, form editIssueTrackerRequest) { _, repo := parseOwnerAndRepo(c) ... if form.EnableExternalTracker != nil { repo.EnableExternalTracker = *form.EnableExternalTracker } if form.ExternalTrackerURL != nil { repo.ExternalTrackerURL = *form.ExternalTrackerURL // ← attacker-controlled URL written directly } ... database.UpdateRepository(repo, false) // ← no admin check before this call } ``` The `wiki()` handler (lines 437–461) follows the same pattern, writing `repo.ExternalWikiURL` directly and calling `UpdateRepository` with no admin gate. ### The web UI imposes a stricter admin requirement for the same operations `cmd/gogs/web.go:472` wraps the entire `/settings` subtree with `reqRepoAdmin`: ```go // cmd/gogs/web.go:425-472 m.Group("/:username/:reponame", func() { m.Group("/settings", func() { m.Combo("").Get(repo.Settings). Post(bindIgnErr(form.RepoSetting{}), repo.SettingsPost) ... }, ...) }, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef()) ``` `context.RequireRepoAdmin()` (defined at `context/repo.go:434-441`) requires `AccessMode >= AccessModeAdmin`: ```go func RequireRepoAdmin() macaron.Handler { return func(c *Context) { if !c.IsLogged || (!c.Repo.IsAdmin() && !c.User.IsAdmin) { c.NotFound() return } } } ``` In the access mode hierarchy, `AccessModeWrite < AccessModeAdmin`. A write-level collaborator satisfies `reqRepoWriter()` but does not satisfy `RequireRepoAdmin()`. The API path provides the write-level collaborator with capabilities that the UI correctly withholds. ### Full execution chain 1. **Attacker precondition**: Attacker is added as a repository collaborator with write access (`AccessMode == AccessModeWrite`). 2. **API call**: `PATCH /api/v1/repos/OWNER/REPO/issue-tracker` with `Authorization: token WRITER_TOKEN` and body `{"enable_external_tracker":true,"external_tracker_url":"https://attacker.example/phish"}`. 3. **Middleware**: `reqRepoWriter()` checks `c.Repo.IsWriter()` → `AccessMode >= AccessModeWrite` → passes. 4. **Handler**: `issueTracker()` sets `repo.EnableExternalTracker = true` and `repo.ExternalTrackerURL = "https://attacker.example/phish"`, then calls `database.UpdateRepository(repo, false)`. No admin check occurs. 5. **Impact**: All visitors to the repository who click the "Issues" tab are redirected to the attacker's server. The native issue tracker is bypassed permanently until a repo admin reverses the change. ## Proof of Concept ```bash # Precondition: attacker is a collaborator with WRITE access, not repo admin. # 1) Redirect the Issues tab to an 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 the Wiki tab to an 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 a mirror sync on a mirrored repository (potential resource abuse) curl -i -X POST "https://TARGET/api/v1/repos/OWNER/REPO/mirror-sync" \ -H "Authorization: token WRITER_TOKEN" # Expected: HTTP 202 Accepted ``` ## Impact - A write-level collaborator can permanently replace the native issue tracker with an external URL under attacker control, redirecting all repository visitors who follow 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 has no way to be removed from having already made the change. - Mirror sync can be triggered repeatedly, potentially causing unnecessary load on the upstream mirror source or consuming network resources. - All three operations are silent — no notification is sent to repo admins when these settings change via the API. ## Recommended remediation ### Option 1: Change middleware to `reqRepoAdmin()` on all three endpoints (preferred) Replace `reqRepoWriter()` with `reqRepoAdmin()` at the route registration level. This is a one-line change per endpoint and aligns the API authorization with the web UI's established policy. ```go // 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) ``` ### Option 2: Add an explicit admin check inside the handlers Add `c.Repo.IsAdmin()` checks at the top of `issueTracker()`, `wiki()`, and `mirrorSync()`. This is less preferred because it duplicates middleware logic in handler code, but it provides defense-in-depth if the route middleware is ever accidentally changed. ```go func issueTracker(c *context.APIContext, form editIssueTrackerRequest) { if !c.Repo.IsAdmin() { c.Status(http.StatusForbidden) return } ... } ``` ## Credit This vulnerability was discovered and reported by [bugbunny.ai](https://bugbunny.ai).

CVE-2026-52808 Affected Gogs.io/gogs Versions

1 component(s)
Fixed Versions:
0.14.3
Product / Package Ecosystem Affected Versions Fixed Version
gogs.io/gogs
Go
< 0.14.3
0.14.3

References

Frequently Asked Questions

What is CVE-2026-52808?
CVE-2026-52808 is a security vulnerability in Gogs.io/gogs involving Gogs's write-level collaborators can mutate admin-only repository settings via API under CWE-269: Improper Privilege Management.
Which Gogs.io/gogs versions are affected?
Affected versions include releases prior to 0.14.3 across affected packages: gogs.io/gogs.
What version fixes CVE-2026-52808?
Upgrading to 0.14.3 (or the latest patched release for your respective branch) resolves the vulnerability.
Is gogs.io/gogs affected?
Yes, gogs.io/gogs is affected in releases prior to 0.14.3. Upgrade your dependency to 0.14.3 or later.
What is the CVSS score of CVE-2026-52808?
CVE-2026-52808 has a CVSS v3.1 base score of 7.1 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L.
What CWE is associated with CVE-2026-52808?
CVE-2026-52808 is classified under CWE-269: Improper Privilege Management (The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.).
How can I check Go dependencies for CVE-2026-52808?
Run the dependency tree command: 'inspect dependencies for gogs.io/gogs'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-268j-37xf-pp52",
  "modified" : "2026-07-21T13:39:55Z",
  "published" : "2026-06-23T17:03:07Z",
  "aliases" : [ "CVE-2026-52808" ],
  "summary" : "Gogs's write-level collaborators can mutate admin-only repository settings via API",
  "details" : "## Summary\n\nThree 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 gated by `reqRepoWriter()` rather than `reqRepoAdmin()`. The equivalent operations in the web UI sit behind `reqRepoAdmin`, which requires `AccessMode >= AccessModeAdmin`. A write-level collaborator (who has `AccessMode == AccessModeWrite < AccessModeAdmin`) can therefore call these API endpoints directly to disable the native issue tracker or wiki, inject attacker-controlled external tracker/wiki URLs that redirect all repository visitors, or trigger mirror sync — none of which they are authorized to do.\n\n## Severity\n\n**High** (CVSS 3.1: 7.1)\n\n`CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L`\n\n- **Attack Vector:** Network — the API endpoints are reachable over HTTP/S.\n- **Attack Complexity:** Low — a single API call is sufficient; no chaining or race condition required.\n- **Privileges Required:** Low — only write-level collaborator access to the targeted repository is needed. The attacker does not need repo-admin or site-admin privileges.\n- **User Interaction:** None — the attacker acts unilaterally.\n- **Scope:** Unchanged — the impact is contained to the targeted repository's settings and its visitors.\n- **Confidentiality Impact:** None — the attacker does not read confidential data directly.\n- **Integrity Impact:** High — the attacker permanently mutates repository configuration, including injecting an external URL that redirects all visitors who click the Issues or Wiki tabs to an attacker-controlled site.\n- **Availability Impact:** Low — disabling the native issue tracker or wiki reduces the availability of those features for all repository participants.\n\n\n## Affected component\n\n- `internal/route/api/v1/api.go` — route registration (lines 365–367)\n- `internal/route/api/v1/repo_repo.go` — `issueTracker()` (line 400), `wiki()` (line 437), `mirrorSync()` (line 463)\n\n## CWE\n\n- **CWE-863**: Incorrect Authorization\n- **CWE-269**: Improper Privilege Management\n\n## Description\n\n### Three admin-equivalent API endpoints are protected by write-level middleware\n\n`api.go:365-367` registers the three settings endpoints with `reqRepoWriter()`:\n\n```go\n// internal/route/api/v1/api.go:365-367\nm.Patch(\"/issue-tracker\", reqRepoWriter(), bind(editIssueTrackerRequest{}), issueTracker)\nm.Patch(\"/wiki\", reqRepoWriter(), bind(editWikiRequest{}), wiki)\nm.Post(\"/mirror-sync\", reqRepoWriter(), mirrorSync)\n```\n\n`reqRepoWriter()` (defined at `api.go:131-138`) passes any user whose repository `AccessMode >= AccessModeWrite`:\n\n```go\nfunc reqRepoWriter() macaron.Handler {\n    return func(c *context.Context) {\n        if !c.Repo.IsWriter() {\n            c.Status(http.StatusForbidden)\n            return\n        }\n    }\n}\n```\n\nThe handlers themselves perform no additional privilege check before mutating state:\n\n```go\n// internal/route/api/v1/repo_repo.go:400-428\nfunc issueTracker(c *context.APIContext, form editIssueTrackerRequest) {\n    _, repo := parseOwnerAndRepo(c)\n    ...\n    if form.EnableExternalTracker != nil {\n        repo.EnableExternalTracker = *form.EnableExternalTracker\n    }\n    if form.ExternalTrackerURL != nil {\n        repo.ExternalTrackerURL = *form.ExternalTrackerURL   // ← attacker-controlled URL written directly\n    }\n    ...\n    database.UpdateRepository(repo, false)   // ← no admin check before this call\n}\n```\n\nThe `wiki()` handler (lines 437–461) follows the same pattern, writing `repo.ExternalWikiURL` directly and calling `UpdateRepository` with no admin gate.\n\n### The web UI imposes a stricter admin requirement for the same operations\n\n`cmd/gogs/web.go:472` wraps the entire `/settings` subtree with `reqRepoAdmin`:\n\n```go\n// cmd/gogs/web.go:425-472\nm.Group(\"/:username/:reponame\", func() {\n    m.Group(\"/settings\", func() {\n        m.Combo(\"\").Get(repo.Settings).\n            Post(bindIgnErr(form.RepoSetting{}), repo.SettingsPost)\n        ...\n    }, ...)\n}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())\n```\n\n`context.RequireRepoAdmin()` (defined at `context/repo.go:434-441`) requires `AccessMode >= AccessModeAdmin`:\n\n```go\nfunc RequireRepoAdmin() macaron.Handler {\n    return func(c *Context) {\n        if !c.IsLogged || (!c.Repo.IsAdmin() && !c.User.IsAdmin) {\n            c.NotFound()\n            return\n        }\n    }\n}\n```\n\nIn the access mode hierarchy, `AccessModeWrite < AccessModeAdmin`. A write-level collaborator satisfies `reqRepoWriter()` but does not satisfy `RequireRepoAdmin()`. The API path provides the write-level collaborator with capabilities that the UI correctly withholds.\n\n### Full execution chain\n\n1. **Attacker precondition**: Attacker is added as a repository collaborator with write access (`AccessMode == AccessModeWrite`).\n2. **API call**: `PATCH /api/v1/repos/OWNER/REPO/issue-tracker` with `Authorization: token WRITER_TOKEN` and body `{\"enable_external_tracker\":true,\"external_tracker_url\":\"https://attacker.example/phish\"}`.\n3. **Middleware**: `reqRepoWriter()` checks `c.Repo.IsWriter()` → `AccessMode >= AccessModeWrite` → passes.\n4. **Handler**: `issueTracker()` sets `repo.EnableExternalTracker = true` and `repo.ExternalTrackerURL = \"https://attacker.example/phish\"`, then calls `database.UpdateRepository(repo, false)`. No admin check occurs.\n5. **Impact**: All visitors to the repository who click the \"Issues\" tab are redirected to the attacker's server. The native issue tracker is bypassed permanently until a repo admin reverses the change.\n\n## Proof of Concept\n\n```bash\n# Precondition: attacker is a collaborator with WRITE access, not repo admin.\n\n# 1) Redirect the Issues tab to an attacker-controlled phishing page\ncurl -i -X PATCH \"https://TARGET/api/v1/repos/OWNER/REPO/issue-tracker\" \\\n  -H \"Authorization: token WRITER_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  --data '{\"enable_issues\":false,\"enable_external_tracker\":true,\"external_tracker_url\":\"https://attacker.example/phish\"}'\n# Expected: HTTP 204 No Content\n\n# 2) Redirect the Wiki tab to an attacker-controlled page\ncurl -i -X PATCH \"https://TARGET/api/v1/repos/OWNER/REPO/wiki\" \\\n  -H \"Authorization: token WRITER_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  --data '{\"enable_wiki\":false,\"enable_external_wiki\":true,\"external_wiki_url\":\"https://attacker.example/phish-wiki\"}'\n# Expected: HTTP 204 No Content\n\n# 3) Force a mirror sync on a mirrored repository (potential resource abuse)\ncurl -i -X POST \"https://TARGET/api/v1/repos/OWNER/REPO/mirror-sync\" \\\n  -H \"Authorization: token WRITER_TOKEN\"\n# Expected: HTTP 202 Accepted\n```\n\n## Impact\n\n- A write-level collaborator can permanently replace the native issue tracker with an external URL under attacker control, redirecting all repository visitors who follow the Issues link to a phishing or malware-serving page.\n- The same redirect attack applies to the Wiki tab via the external wiki URL setting.\n- Both redirects remain active until a repo admin or owner manually reverses the setting; the attacker has no way to be removed from having already made the change.\n- Mirror sync can be triggered repeatedly, potentially causing unnecessary load on the upstream mirror source or consuming network resources.\n- All three operations are silent — no notification is sent to repo admins when these settings change via the API.\n\n## Recommended remediation\n\n### Option 1: Change middleware to `reqRepoAdmin()` on all three endpoints (preferred)\n\nReplace `reqRepoWriter()` with `reqRepoAdmin()` at the route registration level. This is a one-line change per endpoint and aligns the API authorization with the web UI's established policy.\n\n```go\n// internal/route/api/v1/api.go:365-367\nm.Patch(\"/issue-tracker\", reqRepoAdmin(), bind(editIssueTrackerRequest{}), issueTracker)\nm.Patch(\"/wiki\", reqRepoAdmin(), bind(editWikiRequest{}), wiki)\nm.Post(\"/mirror-sync\", reqRepoAdmin(), mirrorSync)\n```\n\n### Option 2: Add an explicit admin check inside the handlers\n\nAdd `c.Repo.IsAdmin()` checks at the top of `issueTracker()`, `wiki()`, and `mirrorSync()`. This is less preferred because it duplicates middleware logic in handler code, but it provides defense-in-depth if the route middleware is ever accidentally changed.\n\n```go\nfunc issueTracker(c *context.APIContext, form editIssueTrackerRequest) {\n    if !c.Repo.IsAdmin() {\n        c.Status(http.StatusForbidden)\n        return\n    }\n    ...\n}\n```\n\n## Credit\n\nThis vulnerability was discovered and reported by [bugbunny.ai](https://bugbunny.ai).",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "gogs.io/gogs"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.14.3"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/gogs/gogs/security/advisories/GHSA-268j-37xf-pp52"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-52808"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/gogs/gogs/pull/8327"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/gogs/gogs/commit/6283462119bd8894f1599d70339b5e823f99954a"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/gogs/gogs"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/gogs/gogs/releases/tag/v0.14.3"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-269", "CWE-863" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-23T17:03:07Z",
    "nvd_published_at" : "2026-06-24T21:16:56Z"
  }
}