fix(security): reject cross-project views in ProjectView Can{Delete,Update} (GHSA-gg93-x632-9ccv)

This commit is contained in:
kolaente
2026-07-19 18:59:34 +02:00
parent 781ffac198
commit 6895a7765e
2 changed files with 12 additions and 3 deletions
+9
View File
@@ -45,6 +45,10 @@ func (pv *ProjectView) CanDelete(s *xorm.Session, a web.Auth) (bool, error) {
return sf.CanDelete(s, a)
}
if _, err := GetProjectViewByIDAndProject(s, pv.ID, pv.ProjectID); err != nil {
return false, err
}
pp := pv.getProject()
return pp.IsAdmin(s, a)
}
@@ -59,6 +63,11 @@ func (pv *ProjectView) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) {
return sf.CanUpdate(s, a)
}
// Reject a view that isn't in the path project before authorizing against it.
if _, err := GetProjectViewByIDAndProject(s, pv.ID, pv.ProjectID); err != nil {
return false, err
}
pp := pv.getProject()
return pp.IsAdmin(s, a)
}
+3 -3
View File
@@ -321,9 +321,9 @@ func TestProjectView(t *testing.T) {
})
t.Run("View from another project", func(t *testing.T) {
// view 5 belongs to project 2. testuser1 admins the path project (1),
// so CanDelete passes — but the view isn't under project 1. The Delete
// guard must 404 before touching project 2's buckets/positions, which
// the old code wiped via a project_view_id-only delete.
// but the view isn't under it, so CanDelete now 404s at the permission
// layer; the Delete guard is a backstop against a project_view_id-only
// wipe of project 2's buckets/positions.
_, err := owned.testDeleteWithUser(nil, map[string]string{"view": "5"})
require.Error(t, err)
assert.Equal(t, http.StatusNotFound, getHTTPErrorCode(err))