mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-26 13:29:52 +09:00
fix(release): validate web attachment renames against allowed types (#38314)
This fixes the web release edit flow so renamed release attachments are validated against `[repository.release] ALLOWED_TYPES`. Previously, the API attachment edit endpoint already enforced release attachment type restrictions, but the web release edit form passed `attachment-edit-*` values into `release_service.UpdateRelease`, which updated attachment names directly without validating the new filename against `setting.Repository.Release.AllowedTypes`. As a result, a user with repository write access could rename an existing release attachment to a disallowed extension through the web UI. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -20,9 +20,11 @@ import (
|
||||
"gitea.dev/modules/graceful"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/modules/repository"
|
||||
"gitea.dev/modules/setting"
|
||||
"gitea.dev/modules/storage"
|
||||
"gitea.dev/modules/timeutil"
|
||||
"gitea.dev/modules/util"
|
||||
"gitea.dev/services/context/upload"
|
||||
notify_service "gitea.dev/services/notify"
|
||||
)
|
||||
|
||||
@@ -319,13 +321,17 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
if deletedUUIDs.Contains(uuid) {
|
||||
continue
|
||||
}
|
||||
if err = upload.Verify(nil, newName, setting.Repository.Release.AllowedTypes); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{
|
||||
UUID: uuid,
|
||||
Name: newName,
|
||||
}, "name"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,11 @@ import (
|
||||
"gitea.dev/models/unittest"
|
||||
user_model "gitea.dev/models/user"
|
||||
"gitea.dev/modules/gitrepo"
|
||||
"gitea.dev/modules/setting"
|
||||
"gitea.dev/modules/test"
|
||||
"gitea.dev/modules/timeutil"
|
||||
"gitea.dev/services/attachment"
|
||||
"gitea.dev/services/context/upload"
|
||||
|
||||
_ "gitea.dev/models/actions"
|
||||
|
||||
@@ -270,6 +273,17 @@ func TestRelease_Update(t *testing.T) {
|
||||
assert.Equal(t, release.ID, release.Attachments[0].ReleaseID)
|
||||
assert.Equal(t, "test2.txt", release.Attachments[0].Name)
|
||||
|
||||
defer test.MockVariableValue(&setting.Repository.Release.AllowedTypes, ".zip")()
|
||||
err = UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, map[string]string{
|
||||
attach.UUID: "test.exe",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.True(t, upload.IsErrFileTypeForbidden(err))
|
||||
release.Attachments = nil
|
||||
assert.NoError(t, repo_model.GetReleaseAttachments(t.Context(), release))
|
||||
assert.Len(t, release.Attachments, 1)
|
||||
assert.Equal(t, "test2.txt", release.Attachments[0].Name)
|
||||
|
||||
// delete the attachment
|
||||
assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, []string{attach.UUID}, nil))
|
||||
release.Attachments = nil
|
||||
|
||||
Reference in New Issue
Block a user