Summary
Gitea's AddReleaseAttachments function accepts attachment UUIDs without verifying that each attachment is not already linked to an issue. An authenticated user with release write permission can re-link an issue-bound attachment to a release they control, exposing attachment metadata (filename, size, download count) through the release page and API, and enabling permanent deletion or renaming of the targeted issue attachment.
Root Cause
The CVE-2026-57886 fix introduced validateAttachmentForIssue to reject attachments already linked to another issue or to a release. This validation is applied to UpdateIssueAttachments and UpdateCommentAttachments, but the release counterpart AddReleaseAttachments was not updated with a symmetric IssueID check.
Affected function: AddReleaseAttachments
Location: models/repo/release.go (line 181)
The function checks:
- attachments[i].RepoID != rel.RepoID (rejects cross-repo)
- attachments[i].ReleaseID != 0 (rejects already-linked-to-release)
Missing check:
- attachments[i].IssueID != 0 (does NOT reject already-linked-to-issue)
Compare with validateAttachmentForIssue (models/issues/issue_update.go:269):
- attachment.RepoID != issue.RepoID (rejects cross-repo)
- attachment.IssueID != 0 && ... (rejects already-linked-to-another-issue)
- attachment.ReleaseID != 0 (rejects already-linked-to-release)
Impact
An authenticated attacker with write access to the Releases unit in a repository can target any issue attachment in the same repository whose UUID is known. Gitea's unit-level team permissions support granting release write without issue access; this is a non-default but supported configuration. The attack requires knowledge of a target attachment UUID, which may leak through notification emails, webhook payloads, RSS/Atom feeds, browser history, or Markdown content viewed before permission changes. UUID enumeration is infeasible (v4, 128-bit random).
After re-linking, the attacker can:
- Disclose metadata: The attachment's filename, UUID, size, and download count appear in the release's attachment list (web page and API endpoint
GET /api/v1/repos/{owner}/{repo}/releases/{id}/assets). Filenames may contain sensitive information.
- Rename the attachment: The release edit interface allows changing the attachment's display name.
- Permanently delete the attachment: The release edit interface can remove the attachment, deleting both the database record and the physical file from storage. The re-link and deletion can occur in a single HTTP request.
File content download is independently protected: GetAttachmentLinkedTypeAndRepoID checks IssueID before ReleaseID, so the download handler verifies issue-level read permission on the original repository. An attacker without issue read access cannot download the file content.
Affected Versions
- Ecosystem: Go
- Package:
code.gitea.io/gitea
- Confirmed affected range:
<= 1.27.3
- Latest release checked: v1.27.3 (GitHub Releases, published 2026-08-29)
- Fix status: not fixed in any published version
The AddReleaseAttachments function has contained the same validation gap since before the CVE-2026-57886 fix was applied. The introduction boundary predates the available git history and cannot be precisely determined. The current go.mod module path is gitea.dev, but the established advisory package coordinate is code.gitea.io/gitea.
Suggested Fix
Add an IssueID check to AddReleaseAttachments in models/repo/release.go, symmetric with the existing ReleaseID check in validateAttachmentForIssue. Specifically, after the existing ReleaseID != 0 check, reject any attachment where IssueID != 0:
if attachments[i].IssueID != 0 {
return util.NewPermissionDeniedErrorf("attachment is already linked to an issue")
}
This prevents issue-bound attachments from being re-linked to releases. The same check should be added to any future attachment linking function. Consider also verifying that the attachment was uploaded by the current user or belongs to the current session.
No interim mitigation is available beyond restricting the Releases write permission to users who also hold issue access in the same repository.
Reported by zx (GitHub: @manus-pi).
Summary
Gitea's
AddReleaseAttachmentsfunction accepts attachment UUIDs without verifying that each attachment is not already linked to an issue. An authenticated user with release write permission can re-link an issue-bound attachment to a release they control, exposing attachment metadata (filename, size, download count) through the release page and API, and enabling permanent deletion or renaming of the targeted issue attachment.Root Cause
The CVE-2026-57886 fix introduced
validateAttachmentForIssueto reject attachments already linked to another issue or to a release. This validation is applied toUpdateIssueAttachmentsandUpdateCommentAttachments, but the release counterpartAddReleaseAttachmentswas not updated with a symmetricIssueIDcheck.Impact
An authenticated attacker with write access to the Releases unit in a repository can target any issue attachment in the same repository whose UUID is known. Gitea's unit-level team permissions support granting release write without issue access; this is a non-default but supported configuration. The attack requires knowledge of a target attachment UUID, which may leak through notification emails, webhook payloads, RSS/Atom feeds, browser history, or Markdown content viewed before permission changes. UUID enumeration is infeasible (v4, 128-bit random).
After re-linking, the attacker can:
GET /api/v1/repos/{owner}/{repo}/releases/{id}/assets). Filenames may contain sensitive information.File content download is independently protected:
GetAttachmentLinkedTypeAndRepoIDchecksIssueIDbeforeReleaseID, so the download handler verifies issue-level read permission on the original repository. An attacker without issue read access cannot download the file content.Affected Versions
code.gitea.io/gitea<= 1.27.3The
AddReleaseAttachmentsfunction has contained the same validation gap since before the CVE-2026-57886 fix was applied. The introduction boundary predates the available git history and cannot be precisely determined. The currentgo.modmodule path isgitea.dev, but the established advisory package coordinate iscode.gitea.io/gitea.Suggested Fix
Add an
IssueIDcheck toAddReleaseAttachmentsinmodels/repo/release.go, symmetric with the existingReleaseIDcheck invalidateAttachmentForIssue. Specifically, after the existingReleaseID != 0check, reject any attachment whereIssueID != 0:This prevents issue-bound attachments from being re-linked to releases. The same check should be added to any future attachment linking function. Consider also verifying that the attachment was uploaded by the current user or belongs to the current session.
No interim mitigation is available beyond restricting the Releases write permission to users who also hold issue access in the same repository.
Reported by zx (GitHub: @manus-pi).