mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-07-20 21:14:30 -05:00
fix(security): reject cross-project views in ProjectView Can{Delete,Update} (GHSA-gg93-x632-9ccv)
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user