CVE-2026-25120 — gogs
Fix: gogs/gogs@1b226caCVE-2026-25120 is a CWE-639 vulnerability in gogs.io/gogs. A fix is available for gogs.io/gogs — see the affected versions and patch details below.
Gogs Allows Cross-Repository Comment Deletion via DeleteComment
Exploitation Status
No confirmed exploitation observed yet
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-25120.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Real-World Exposure
gogs.io/gogsReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
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:
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:
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
- Two users: Alice (attacker) and Bob (victim)
- Alice is admin of
alice/attacker-repo - Bob has created an issue with a comment on
bob/victim-repo - Attacker needs to obtain the comment ID from victim's repository (e.g., ID: 42)
HTTP Request
POST /alice/attacker-repo/issues/comments/42/delete HTTP/1.1
Host: gogs.example.com
Cookie: i_like_gogs=<alice_session_token>
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | gogs.io/gogs | all versions | 0.14.0go get gogs.io/gogs@v0.14.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for gogs.io/gogs, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update gogs.io/gogs to 0.14.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-25120 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-25120 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2026-25120. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is CVE-2026-25120 in your dependencies?
O3 Security finds CVE-2026-25120 across Go dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.