CVE-2026-25120: Gogs Allows Cross-Repository Comment Deletion via DeleteComment
IDOR: Cross-Repository Comment Deletion via DeleteComment
Summary
The POST /:owner/:repo/issues/comments/:id/delete endpoint does not verify that the comment belongs to the repository specified in the URL. This allows a repository administrator to delete comments from any other repository by supplying arbitrary comment IDs, bypassing authorization controls.
Vulnerability Details
| Field | Value | |-------|-------| | Affected File | internal/route/repo/issue.go | | Affected Function | DeleteComment (lines 955-968) | | Secondary File | internal/database/comment.go | | Secondary Function | DeleteCommentByID (lines 505-520) |
Root Cause
The vulnerability exists due to insufficient authorization validation in the comment deletion flow:
1. Missing Repository Ownership Check in DeleteComment
In internal/route/repo/issue.go, the function retrieves a comment by ID without verifying repository ownership:
go func DeleteComment(c context.Context) { comment, err := database.GetCommentByID(c.ParamsInt64(":id")) if err != nil { c.NotFoundOrError(err, "get comment by ID") return }
// Only checks if user is comment poster OR admin of the CURRENT repo (from URL) if c.UserID() != comment.PosterID && !c.Repo.IsAdmin() { c.NotFound() return } else if comment.Type != database.CommentTypeComment { c.Status(http.StatusNoContent) return }
// No verification that comment.IssueID belongs to c.Repo.Repository.ID! if err = database.DeleteCommentByID(c.User, comment.ID); err != nil { c.Error(err, "delete comment by ID") return }
c.Status(http.StatusOK) }
2. Database Layer Performs No Authorization
In internal/database/comment.go, the deletion function performs no repository validation:
go func DeleteCommentByID(doer User, id int64) error { comment, err := GetCommentByID(id) if err != nil { if IsErrCommentNotExist(err) { return nil } return err }
// Directly deletes without checking repository ownership sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err }
if , err = sess.ID(comment.ID).Delete(new(Comment)); err != nil { // ... } // ... }
Proof of Concept
Prerequisites
1. Two users: Alice (attacker) and Bob (victim) 2. Alice is admin of alice/attacker-repo 3. Bob has created an issue with a comment on bob/victim-repo 4. Attacker needs to obtain the comment ID from victim's repository (e.g., ID: 42)
HTTP Request
http POST /alice/attacker-repo/issues/comments/42/delete HTTP/1.1 Host: gogs.example.com Cookie: ilikegogs=<alicesessiontoken>
Other sources
Gogs is an open source self-hosted Git service. In versions 0.13.4 and below, the DeleteComment API does not verify that the comment belongs to the repository specified in the URL. This allows a repository administrator to delete comments from any other repository by supplying arbitrary comment IDs, bypassing authorization controls. The DeleteComment function retrieves a comment by ID without verifying repository ownership and the Database function DeleteCommentByID performs no repository validation. This issue has been fixed in version 0.14.0.
— MITRE
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2026-25120?
CVE-2026-25120 has been classified with a high severity due to the potential for unauthorized comment deletion across repositories.
How do I fix CVE-2026-25120?
To fix CVE-2026-25120, upgrade to version 0.14.0 or later of the affected Gogs package.
What type of vulnerability is CVE-2026-25120?
CVE-2026-25120 is an Insecure Direct Object Reference (IDOR) vulnerability.
Who is affected by CVE-2026-25120?
Repositories running Gogs versions from 0.13.4 and earlier are vulnerable to CVE-2026-25120.
What impact does CVE-2026-25120 have on users?
CVE-2026-25120 allows repository administrators to delete comments from other repositories, potentially leading to data loss and integrity issues.