mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-17 17:15:08 +00:00
4b8220a250
The sweep after #1685 turned up the same leak two widgets further down the same controller. largestFiles() and expiredFiles() already take the viewer -- to decide whether their rows get links -- but queried with a bare File::query(), so a client-scoped staff member's dashboard named files belonging to clients they hold nothing of. The note above largestFiles() says a link that 403s is accepted rather than adding per-row scope checks. That reasoning is about the link. A row that should not be there at all is a different problem, and the name is the part that leaks: "Q3 delinquent accounts" says plenty without ever being downloadable. Scoping the query is also cheaper than the per-row check that note declined -- StaffLibraryScope builds a scoped user's query once per request. Reachable in the default configuration, unlike the last few of these: the Client Manager role ships client-scoped and holds view_statistics. topClientsByStorage() goes with them; it names clients rather than files, which is the thing MembershipRequest::approvableBy and ActivityLogScope already exist to keep inside a roster. counters() and transferSeries() stay installation-wide, and now say so. A total carries no names -- "417 files" tells a scoped viewer nothing about whose they are -- and if that ever stops being the line, both move together. One consequence worth stating rather than discovering: scopeVisibleToClient ends in notExpired(), so a scoped viewer's expired-files widget now lists only their own expired uploads, not a client's. Safe, and under-inclusive -- telling them about a file auto-delete is about to take needs a library query that keeps expired rows, which is a boundary to decide rather than to invent inside a leak fix.