ssh-mcp 2.11.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/build/policy/classifier.js +1022 -82
- package/build/policy/engine.js +42 -20
- package/build/policy/reader-grammar.js +247 -0
- package/build/tools/pipeline.js +10 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -526,11 +526,28 @@ never widen. Widening happens here or not at all.
|
|
|
526
526
|
|
|
527
527
|
Every command is classified before execution:
|
|
528
528
|
|
|
529
|
-
- **read-only**: Allowlisted commands (`ls`, `cat`, `grep`, `df`, `stat`, `systemctl status`, ...)
|
|
529
|
+
- **read-only**: Allowlisted commands (`ls`, `cat`, `grep`, `df`, `stat`, `systemctl status`, ...),
|
|
530
|
+
and only when every argument is provably data under a grammar declared for that binary — see
|
|
531
|
+
below
|
|
530
532
|
- **safe**: Non-destructive mutations (`npm install`, `git pull`, ...)
|
|
531
533
|
- **destructive**: mutations that need approval (`rm -rf /tmp/build`, ...)
|
|
532
534
|
- **privileged**: `sudo`, `su`, `doas`, `pkexec`
|
|
533
535
|
|
|
536
|
+
**`read-only` is granted by argument grammar, not by binary name alone.** An allowlisted
|
|
537
|
+
binary's argument list is checked word by word against a grammar declared for it
|
|
538
|
+
(`src/policy/reader-grammar.ts`); an option the grammar does not list, an abbreviation of one
|
|
539
|
+
it does, a short-option cluster with an unlisted letter, an argument carrying an unquoted
|
|
540
|
+
shell glob (`*`, `?`, `[`), or an operand shaped like something
|
|
541
|
+
the binary would write to, all fall the whole command to `safe` instead. This is what a
|
|
542
|
+
`readOnly` profile is confined to, what `viewer` holds on prod and staging (on dev the viewer
|
|
543
|
+
holds `safe` too), and what `read-command`
|
|
544
|
+
requires — all of these refuse `safe` except the viewer on dev, so a command that used to
|
|
545
|
+
run under the old, name-only
|
|
546
|
+
rule can now be refused. The refusal names the rejected word (for example, `` `journalctl` is
|
|
547
|
+
read-only only with the options and operands its grammar lists; `--foo` is not accepted
|
|
548
|
+
there. ``), so the caller can see which spelling of the same command still works. See
|
|
549
|
+
[SECURITY.md](./SECURITY.md) for the residual risks this leaves open.
|
|
550
|
+
|
|
534
551
|
A separate **forbidden** list is never allowed, whatever the role or approval
|
|
535
552
|
policy: `rm -rf /`, `mkfs`, `dd of=/dev/`, `shutdown`, `curl|sh`, fork bombs,
|
|
536
553
|
writes to `/etc/cron`, `/etc/systemd` or `authorized_keys`, `iptables -F`, and
|