Plug-ins: a permission grant covers only the module that was approved

A grant records the module's SHA-256, but only its permissions were
compared, so a module with other bytes under a granted id inherited the
grant when it listed no new permission.

A grant now covers a module only when the id, the SHA-256 and every
listed permission match. plugin.inspect reports needsApproval for a
changed module, plugin.install refuses it without a new grant and leaves
the installed module and its grant as they are, Install Plug-in and
File > Open ask again, and the plug-in store and plug-in folders skip it.
The same bytes install again without asking, and a module with no
permissions list or an empty one needs no grant. A grant whose hash is
not 64 lower-case hexadecimal digits covers nothing.

plugin.install still trusts the client that sends grant; the docs say so.
This commit is contained in:
dotCooCoo
2026-11-08 08:40:00 -08:00
parent 0a702cc0a5
commit 91d9639e6a
9 changed files with 232 additions and 47 deletions
+4 -2
View File
@@ -6097,8 +6097,10 @@ runs it where it is called, so the call may take minutes; `notifications/cancell
A plug-in whose manifest lists permissions (`permissions` in its `plugin.inspect` entry, with `needsApproval: true`)
installs only with `grant: [permission]` listing every one of them: show the user the list and ask first, and pass
the entry's `hash` as `hash` so that a module that changed since is refused. Without `grant`, `plugin.install` returns
an error naming the permissions needed. The grant is kept with the module's hash; a module
with the same id that lists no new permission installs without `grant`, and `plugin.remove` forgets the grant. A
an error naming the permissions needed. The grant is kept with the module's hash and covers only that module: the
same bytes install again without `grant`, and a module with other bytes has `needsApproval: true` and needs a new
`grant` even when it lists the same permissions. `plugin.install` does not check that a person approved `grant`: it
trusts the client that sends it. `plugin.remove` forgets the grant. A
filter without `doc.write` or `state` that returns output needing them gets an error and the document is unchanged.
A plug-in of API level 2 (`api: 2` in its entry) that lists `progress` may report its progress, see Cancel and write
log lines: `notifications/cancelled` makes its `vc_cancelled` return 1, and its log lines go to the server's log