{"schema_version":"1.7.3","id":"GHSA-cv22-72px-f4gh","published":"2026-02-17T18:42:08Z","modified":"2026-02-23T19:26:04.055032Z","aliases":["CVE-2026-25229","GO-2026-4499"],"summary":"Gogs has an Authorization Bypass Allows Cross-Repository Label Modification in Gogs","details":"### **Summary**\nA broken access control vulnerability in Gogs allows authenticated users with write access to any repository to modify labels belonging to other repositories. The `UpdateLabel` function in the Web UI (`internal/route/repo/issue.go`) fails to verify that the label being modified belongs to the repository specified in the URL path, enabling cross-repository label tampering attacks.\n\n### **Details**\nThe vulnerability exists in the Web UI's label update endpoint `POST /:username/:reponame/labels/edit`. The handler function `UpdateLabel` uses an incorrect database query function that bypasses repository ownership validation:\n\n**Vulnerable Code** (`internal/route/repo/issue.go:1040-1054`):\n\n```plain\nfunc UpdateLabel(c *context.Context, f form.CreateLabel) {\n    l, err := database.GetLabelByID(f.ID)  // ❌ No repository validation\n    if err != nil {\n        c.NotFoundOrError(err, \"get label by ID\")\n        return\n    }\n\n    // ❌ Missing validation: l.RepoID != c.Repo.Repository.ID\n    l.Name = f.Title\n    l.Color = f.Color\n    if err := database.UpdateLabel(l); err != nil {\n        c.Error(err, \"update label\")\n        return\n    }\n    c.RawRedirect(c.Repo.MakeURL(\"labels\"))\n}\n```\n\n**Root Cause**:\n\n1. The function calls `database.GetLabelByID(f.ID)` which internally passes `repoID=0` to the ORM layer\n2. According to code comments in `internal/database/issue_label.go:147-166`, passing `repoID=0` causes the ORM to ignore repository restrictions\n3. No validation checks whether `l.RepoID == c.Repo.Repository.ID` before updating\n4. The middleware `reqRepoWriter()` only validates write access to the repository in the URL path, not the label's actual repository\n\n**Inconsistency with Other Functions**:\n\n+ `NewLabel`: Correctly sets `RepoID = c.Repo.Repository.ID`\n+ `DeleteLabel`: Correctly uses `database.DeleteLabel(c.Repo.Repository.ID, id)`\n+ API `EditLabel`: Correctly uses `database.GetLabelOfRepoByID(c.Repo.Repository.ID, id)`\n\n- ****Only `UpdateLabel` in ****Web UI**** uses the vulnerable pattern****\n\n### **PoC**\n**Prerequisites**:\n\n+ Two user accounts: Alice (attacker) and Bob (victim)\n+ alice has written access to repo-a\n+ Bob owns repo-b with labels\n\n**Step 1: Identify Target Label ID**\n\n1. Login as bob, navigate to bob/repo-b/labels\n2. Open browser DevTools (F12) → Network tab\n3. Click edit on any label\n4. Observe the form data: id=<LABEL_ID>\n5. Example: id=1\n\n**Step 2: Execute Attack**\n\n```plain\n# Login as alice, get session cookie\n# Open DevTools → Application → Cookies → i_like_gogs\n# Copy the cookie value\n\n# Send malicious request\ncurl -X POST \"http://localhost:3000/alice/repo-a/labels/edit\" \\\n  -H \"Cookie: i_like_gogs=<ALICE_SESSION_COOKIE>\" \\\n  -H \"Content-Type: application/x-www-form-urlencoded\" \\\n  -d \"id=1&title=HACKED-BY-ALICE&color=%23000000\"\n\n# Expected response: 302 Found (redirect)\n```\n\n**Step 3: Verify Impact**\n\n1. Login as bob\n2. Navigate to bob/repo-b/labels\n3. Observe: Label \"P0-Critical\" is now \"HACKED-BY-ALICE\" with black color\n\n### **Impact**\n1. **Issue Classification Disruption**: Modify critical labels (e.g., \"P0-Critical\" → \"P3-Low\") causing urgent issues to be deprioritized\n\n2. **Security Issue Concealment**: Change \"security\" labels to \"documentation\" to hide vulnerability reports from security teams\n\n3. **Workflow**** Sabotage**: Alter labels used in CI/CD automation, breaking deployment pipelines\n\n4. **Mass Disruption**: Batch modifies all labels across multiple repositories using ID enumeration\n\n**Recommended Fix**:\n\n```plain\nfunc UpdateLabel(c *context.Context, f form.CreateLabel) {\n    l, err := database.GetLabelOfRepoByID(c.Repo.Repository.ID, f.ID)\n    if err != nil {\n        c.NotFoundOrError(err, \"get label of repository by ID\")\n        return\n    }\n    // Now label ownership is validated at database layer\n    l.Name = f.Title\n    l.Color = f.Color\n    if err := database.UpdateLabel(l); err != nil {\n        c.Error(err, \"update label\")\n        return\n    }\n    c.RawRedirect(c.Repo.MakeURL(\"labels\"))\n}\n```","affected":[{"package":{"name":"gogs.io/gogs","ecosystem":"Go","purl":"pkg:golang/gogs.io/gogs"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.14.0"}]}],"database_specific":{"last_known_affected_version_range":"<= 0.13.4","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/02/GHSA-cv22-72px-f4gh/GHSA-cv22-72px-f4gh.json"}}],"references":[{"type":"WEB","url":"https://github.com/gogs/gogs/security/advisories/GHSA-cv22-72px-f4gh"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-25229"},{"type":"WEB","url":"https://github.com/gogs/gogs/commit/643a6d6353cb6a182a4e1f0720228727f30a3ad2"},{"type":"PACKAGE","url":"https://github.com/gogs/gogs"}],"database_specific":{"cwe_ids":["CWE-284"],"github_reviewed":true,"github_reviewed_at":"2026-02-17T18:42:08Z","nvd_published_at":"2026-02-19T07:17:45Z","severity":"MODERATE"},"severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N"}]}