Decide guest grants explicitly instead of by permission name
guest_grantable_permissions() opened any permission whose name ended
'.view' or '.read' to the guest role, on the reasoning that reading is
the safe default. That is true of a permission gating a list of asset
numbers and false of one gating bytes, and a suffix cannot tell them
apart. Twenty-four of eighty-five qualified and none had been decided:
applications.view reached the SYSTEM-context PowerShell bodies and
the installer binaries pushed to bays
backups.view returned the full payload that the separate
backups.download permission exists to protect
assets.view gated a global search that queries the staff
directory, USB history and network inventory with
no per-domain check of its own
audit.view usernames, addresses, the before/after of every
settings.view change, and every setting row - both admin
category, opened by naming alone
users.view gates nothing at all; list_users is
require_role('admin')
Every entry is now declared, by CORE_GUEST_GRANTABLE or by the plugin
that owns the permission, having read what its routes actually return.
Adding one is a code change, which is the point: it puts the decision
in a diff rather than in a suffix.
The two routes serving script bodies and installer packages move to a
new applications.download permission, which is not grantable, so a site
can still open the catalogue metadata to its floor without the bytes
going with it.
The declared set preserves the grants this site had already chosen:
applications.view, computers.view, endpoints.view, reports.view,
tools.secrets, warranty.view.
Two known gaps are recorded on the hooks that expose them rather than
silently carried: the computer serializer publishes every column plus
resolved rdp:// and vnc:// links, and the per-asset endpoint panels are
keyed on a small integer so walking ids reconstructs much of the roster
that endpoints.fleet exists to protect. Neither is widened here.
A shipped test was granting guests audit.view and passing.
Scope: product
(cherry picked from commit 347402896c)
This commit is contained in:
@@ -107,17 +107,24 @@ class BasePlugin(ABC):
|
||||
def get_guest_grantable_permissions(self) -> List[str]:
|
||||
"""Permissions this plugin allows a site to grant to the GUEST role.
|
||||
|
||||
A guest is anyone with no account. Any `.view` or `.read` permission is
|
||||
grantable without asking a plugin - reading is the safe default. This
|
||||
hook is for the exception: a WRITE that is genuinely meant to be usable
|
||||
by somebody who never signs in.
|
||||
A guest is anyone with no account. EVERY permission of this plugin's
|
||||
that a site may grant one has to be named here, reads included.
|
||||
|
||||
Reads used to be automatic: anything ending `.view` or `.read` was
|
||||
grantable. That treats a name as a decision, and it went wrong in the
|
||||
obvious way - permissions that gated installer bytes, backup payloads
|
||||
and a search across the staff directory were all anonymous-grantable
|
||||
because of how they were spelled. So the plugin that owns a permission
|
||||
now says, having looked at what its routes return.
|
||||
|
||||
Naming one here does not open it. It makes the checkbox available in
|
||||
the role grid; a site still has to tick it. Return [] (the default) and
|
||||
none of this plugin's writes can ever be made anonymous.
|
||||
nothing of this plugin's can be made anonymous.
|
||||
|
||||
The bar: could this action be attributed to nobody, forever, and still
|
||||
be defensible in the audit log? If not, leave it out.
|
||||
The bar for a read: could an anonymous visitor hold this, forever, and
|
||||
would the site be content with everything the routes return - every
|
||||
column of every serializer, not just the ones the UI happens to show?
|
||||
For a write, add that the act can never be attributed to anybody.
|
||||
"""
|
||||
return []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user