Gate each search domain on its own permission
Global search is gated on assets.view, and that was the whole check. Behind it the route queried twelve domains: applications, the knowledge base, guides, the staff directory, assets, measuring tools, USB devices, printed parts, custom fields, notifications, hostnames, and vendor and model reference data, plus addresses and subnets for an IP-shaped query. None of them consulted their own permission. So anyone who could look up an asset number could also read the staff directory out of the HR database, the USB checkout history and who holds which drive, and the network inventory. The SEARCH_DOMAINS settings look like they bound this but they are site feature toggles, not authorization. Each domain now answers only to a caller who holds its permission. Assets, custom fields and vendor/model stay on assets.view because all three emit asset rows routed to asset pages. caller_holds rather than require_permission: refusing the whole request because one domain is off-limits would make search useless to anyone holding less than everything. A domain the caller cannot see contributes nothing and the rest still answers. This is what makes assets.view safe to grant the guest role again. It left the grantable set in3474028because of the leak above, and that took the shop floor's asset lookup with it - a signed-out visitor at a machine could no longer search for the asset number in front of them. Now the grant reaches assets and nothing else. The first version of the leak test passed with the gates removed. The staff directory is an external HR database and is unreachable under test, so the domain silently returned nothing and the assertion proved nothing. It patches _employee_rows now, and fails when the gate goes. Scope: product (cherry picked from commit0a01ddcf25)
This commit is contained in:
17
CHANGELOG.md
17
CHANGELOG.md
@@ -128,6 +128,23 @@ ADR-007 and ADR-002.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Global search answered twelve domains behind one permission.** The route is
|
||||
gated on `assets.view`, and that was the entire check: looking up an asset
|
||||
number also read out of the staff directory, the USB checkout history, the
|
||||
notification log and the network inventory, none of which consult their own
|
||||
permission. The `SEARCH_DOMAINS` settings are site feature toggles, not
|
||||
authorization, and were never doing that job. Each domain now answers only to
|
||||
a caller holding its permission - `employees.view` for the directory,
|
||||
`usb.view` for checkouts, `network.view` for address and subnet matches,
|
||||
`computers.view` for hostnames. Asset, custom-field and vendor/model results
|
||||
stay on `assets.view`, since all three emit asset rows. The check is
|
||||
`caller_holds` rather than `require_permission`: a search that refused the
|
||||
whole request because one domain was off-limits would be useless, so a domain
|
||||
the caller cannot see simply contributes nothing. This is also what makes
|
||||
`assets.view` safe to hand to the guest role again, which is what lets a
|
||||
signed-out visitor look up an asset number without also getting the staff
|
||||
directory.
|
||||
|
||||
- **The printer supplies card was ordered by printer name, so the emptiest
|
||||
cartridge was not first and sometimes was not shown at all.** Rows sorted on
|
||||
"is critical" and then alphabetically, and critical is everything at or below
|
||||
|
||||
Reference in New Issue
Block a user