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:
@@ -162,9 +162,6 @@ def full_permission_catalog(include_disabled=False):
|
||||
# Each one has been read against what its routes actually return.
|
||||
#
|
||||
# Deliberately absent, with the reason, so nobody re-adds them by reflex:
|
||||
# assets.view - gates the global search, which queries the staff directory
|
||||
# and the USB, notification and network domains with no
|
||||
# per-domain check of its own
|
||||
# settings.view - every setting row, and secret masking is a substring test
|
||||
# audit.view - usernames, addresses, and the before/after of every change
|
||||
# users.view - gates nothing; list_users is require_role('admin')
|
||||
@@ -174,6 +171,11 @@ CORE_GUEST_GRANTABLE = {
|
||||
# Catalogue metadata. Safe only because the bytes moved to
|
||||
# applications.download, which is not grantable.
|
||||
'applications.view',
|
||||
# Assets, and the global search over them. Safe only because search now
|
||||
# gates each domain on its own permission: holding this reaches assets and
|
||||
# nothing else, where it used to reach the staff directory and the USB,
|
||||
# notification and network domains too.
|
||||
'assets.view',
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user