fix(kanban): authorize body task_id when moving a task into a bucket (GHSA-5pg6-m483-7vrg)

This commit is contained in:
kolaente
2026-07-19 18:59:34 +02:00
parent 37c35c64fb
commit 36cdc2ce2b
2 changed files with 35 additions and 1 deletions
+9 -1
View File
@@ -56,7 +56,15 @@ func (b *TaskBucket) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) {
ProjectID: b.ProjectID,
ProjectViewID: b.ProjectViewID,
}
return bucket.canDoBucket(s, a)
canDoBucket, err := bucket.canDoBucket(s, a)
if err != nil || !canDoBucket {
return false, err
}
// The task comes from the request body and may live in a different
// project than the bucket, so it needs its own write check.
task := &Task{ID: b.TaskID}
return task.CanWrite(s, a)
}
func (b *TaskBucket) upsert(s *xorm.Session) (err error) {
+26
View File
@@ -115,6 +115,32 @@ func TestTaskBucketV2(t *testing.T) {
assert.Contains(t, rec.Body.String(), fmt.Sprintf(`"code":%d`, models.ErrCodeProjectViewDoesNotExist))
})
t.Run("task from a foreign project is forbidden", func(t *testing.T) {
e, err := setupTestEnv()
require.NoError(t, err)
// testuser1 owns project 1 but has no access to project 20 (owner 13),
// where task 34 lives. The body task id must be authorized, not just
// the URL bucket (GHSA-5pg6-m483-7vrg).
token := humaTokenFor(t, &testuser1)
rec := humaRequest(t, e, http.MethodPut, fmt.Sprintf(path, 3), `{"task_id":34}`, token, "")
require.Equal(t, http.StatusForbidden, rec.Code, "body: %s", rec.Body.String())
db.AssertMissing(t, "task_buckets", map[string]interface{}{
"task_id": 34,
"project_view_id": 4,
})
// The task's own bucket placement stays untouched.
db.AssertExists(t, "task_buckets", map[string]interface{}{
"task_id": 34,
"bucket_id": 5,
}, false)
db.AssertExists(t, "tasks", map[string]interface{}{
"id": 34,
"done": false,
}, false)
})
t.Run("no write access is forbidden", func(t *testing.T) {
e, err := setupTestEnv()
require.NoError(t, err)