Repository navigation
fix(security): harden item_get, vault allow-list, op_run, and CI (v4.0.4) - #32
Closed
CakeRepository wants to merge 1 commit into
Closed
CakeRepository wants to merge 1 commit into
CakeRepository wants to merge 1 commit into
Conversation
…0.4) Security release from an internal review. - item_get: deny-by-default field masking. SSH private keys, TOTP seeds, and card numbers were returned in plaintext without reveal. - Vault allow-list (OP_MCP_ALLOWED_VAULTS) is now enforced by every tool and resource, and op:// references are also checked by the vault they resolve to, not only as written (new src/vault-access.ts). - op_run redaction (new src/redaction.ts): single-pass masking over the original output, so overlapping secrets no longer leak each other's remainder; also masks base64 (any alignment), JSON/URL-escaped, and multi-line/CRLF forms. - op_run: output cap enforced while the command runs (memory-exhaustion DoS), timeouts kill the whole process tree and always return, the credential env scrub is case-insensitive, and the tool description no longer overclaims. - CI: remove the leftover issue_comment-triggered mcp-v2-migration.yml (contents: write, triggerable by any GitHub user). publish.yml passes the release tag via env, does not persist credentials, and splits build/test/pack (npm ci --ignore-scripts, no OIDC) from a publish-only job that alone holds id-token: write. - macOS Keychain lookup runs /usr/bin/security; startup warning when the token is passed on the command line. - Docs and CHANGELOG updated; version bumped to 4.0.4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CakeRepository
added a commit
that referenced
this pull request
Oct 4, 2026
#33) * fix(security): harden item_get, vault allow-list, op_run, and CI (v4.0.4) Security release from an internal review. - item_get: deny-by-default field masking. SSH private keys, TOTP seeds, and card numbers were returned in plaintext without reveal. - Vault allow-list (OP_MCP_ALLOWED_VAULTS) is now enforced by every tool and resource, and op:// references are also checked by the vault they resolve to, not only as written (new src/vault-access.ts). - op_run redaction (new src/redaction.ts): single-pass masking over the original output, so overlapping secrets no longer leak each other's remainder; also masks base64 (any alignment), JSON/URL-escaped, and multi-line/CRLF forms. - op_run: output cap enforced while the command runs (memory-exhaustion DoS), timeouts kill the whole process tree and always return, the credential env scrub is case-insensitive, and the tool description no longer overclaims. - CI: remove the leftover issue_comment-triggered mcp-v2-migration.yml (contents: write, triggerable by any GitHub user). publish.yml passes the release tag via env, does not persist credentials, and splits build/test/pack (npm ci --ignore-scripts, no OIDC) from a publish-only job that alone holds id-token: write. - macOS Keychain lookup runs /usr/bin/security; startup warning when the token is passed on the command line. - Docs and CHANGELOG updated; version bumped to 4.0.4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(resources): make resources readable with onepassword:// URIs (v5.0.0) Every resources/read failed with -32602 "Resource URI ... is invalid": the SDK parses the URI with new URL() before dispatching, and a scheme cannot start with a digit (RFC 3986 3.1), so no 1password:// URI ever reached a handler. - Resource URIs now use the onepassword:// scheme. Breaking for anything that hard-coded the old URIs, hence 5.0.0. - onepassword://vaults/{vaultId}/items is a ResourceTemplate and reads vaultId from the percent-decoded template variables. It was a static resource whose URI was the literal template string, so no concrete vault URI could match it. - buildServer() moved to src/server.ts (re-exported from index.ts) so tests can build the real server without starting stdio. - tests/resources.e2e.test.ts: a real MCP client reads every advertised resource from serveStdio(() => buildServer()) over an in-memory transport, in both the 2025 and 2026-07-28 protocol eras. Adds the @modelcontextprotocol/client dev dependency. - README, agents.md, CONTRIBUTING, and CHANGELOG updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(resources): cover the vault allow-list end to end Read onepassword://vaults and the items template through the real MCP client with OP_MCP_ALLOWED_VAULTS set, in both protocol eras. The vault listing is filtered, items of a vault outside the list are refused before items.list() runs, and the check sees the percent-decoded vaultId, so an encoded ID can't slip past it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(changelog): fold the unreleased 4.0.4 notes into 5.0.0 The security hardening from #32 ships in the same release as the resource URI change, so 4.0.4 is never published. Move its Security and Changed notes into the 5.0.0 entry, name the items template in the allow-list note, and point the README and agents.md at 5.0.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Superseded by #33, which merged these changes together with the resource URI fix (onepassword://). They shipped in v5.0.0 (https://github.com/CakeRepository/1Password-MCP/releases/tag/v5.0.0) instead of a separate 4.0.4 release. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security release v4.0.4, from an internal review of the repo. Full details are in the
CHANGELOG.md4.0.4 entry.Vulnerabilities fixed
mcp-v2-migration.yml(a leftover one-time runner withcontents: write) by commenting/run-mcp-v2-migrationon a PR. It rannpm installwith the write token persisted in.git/config.item_getwithreveal: falsereturned SSH private keys, TOTP seeds and card numbers in plaintext; onlyConcealedfields were masked.OP_MCP_ALLOWED_VAULTSwas enforced by 2 of 15 tools, so it could be bypassed withpassword_read/item_get. It also checked only the reference as written.src/vault-access.ts: enforced by every tool and resource; references are also checked by the vault they resolve to; fails closedop_runredaction was order-dependent. A shorter secret inside a longer one (e.g. a username insideuser:password) got masked first, which leaked the rest. Encoded forms weren't masked at all.src/redaction.ts: single pass over the original output with overlapping matches merged; also masks base64 (all 3 alignments), JSON/URL-escaped and multi-line/CRLF formsop_runbuffered output without limit; the 5 MiB cap applied only after exit, so a command likeyescould exhaust memory and crash the serverop_runtimeout killed only the shell, and a backgrounded process holding the pipes could hang the call forevertaskkill /Ton Windows) and always returns within timeout + 2.5 spublish.ymlinterpolated${{ github.event.release.tag_name }}into shell, and dependency code ran in the job holdingid-token: writeenv;persist-credentials: false; build/test/pack (npm ci --ignore-scripts, no OIDC) split from a publish-only jobsecuritythroughPATH/usr/bin/securityThe
op_runtool description no longer claims plaintext is "NEVER" returned. Redaction is best effort and protects against accidental disclosure; it is not a sandbox.Behaviour changes (also under Changed in the CHANGELOG)
vaultIdneed an ID, not a name. With an allow-list set, each guarded call makes one extravaults.listread.item_gethides more fields by default. SSH keys, OTP seeds and card numbers now needreveal: true.op://references are rejected locally byitem_getandpassword_read.Testing
npm run clean && npm ci && npm run build && npm run lint && npm teston Windows (Node 22): 386 passed, 1 skipped (POSIX-only).npm ci --ignore-scripts+ build + test verified on Linux Node 24 before adding it to the publish build job.tools/list(15 tools);op_runchild does not see the server token;publish.ymlwas validated structurally (YAML parse,needs/outputs/artifact linkage, no${{inrun:), and its pack step was simulated locally.Not in this PR
1password://resources were already unreadable:new URL()rejects a scheme that starts with a digit. That is tracked separately.🤖 Generated with Claude Code