1.8 KiB
type, pr
| type | pr |
|---|---|
| Fixed | 1481 |
Capability --integrity is now verified or rejected per source, and hook commands are confined to the bundle — a supplied --integrity pin was silently dropped for npm, git, and local capability sources (only the tarball source verified it), so a user could believe content was pinned when it was not. npm now verifies the pin over the npm pack .tgz bytes; git and local sources, which have no single hashable artifact, now reject a supplied --integrity with an actionable error instead of ignoring it. Separately, a capability hook's relative script was written verbatim as the hook command, so it resolved against the working directory (not the capability bundle) at hook-exec time and a crafted relative path could escape the bundle; the command is now resolved against the capability's own install dir and realpath-confined to it, then written as an absolute path. That absolute command is consumed by a shell, which exposed two further problems now fixed: (1) a manifest could ship a file literally named run.sh; touch /tmp/pwn (filenames may legally contain ;, spaces, $, backtick, |, newline) and declare it as the hook script, so the emitted command injected a second shell command even though the file lived inside the bundle — the validator now rejects any hook script path outside a conservative [A-Za-z0-9._/-] allowlist (no whitespace, shell metacharacters, leading -, absolute path, or ..), failing the install/load loudly, and the confinement helper mirrors the same rejection defensively; (2) the absolute path begins with the install-home directory, which commonly contains spaces (e.g. /Users/Bob Smith/.claude/...) and word-split or broke when written unquoted — the emitted command is now POSIX single-quoted so the install prefix can neither break nor inject. (#1460)