Skip to content

fix(mcp): read the uvx --from and pipx --spec requirement as the package - #35

Merged
controlloop-security merged 1 commit into
mainfrom
fix-uvx-from-pin
Oct 30, 2026
Merged

controlloop-security merged 1 commit into
mainfrom
fix-uvx-from-pin

Conversation

@controlloop-security

Copy link
Copy Markdown
Owner

Summary

An MCP server launched as uvx --from pkg==1.2 tool was recorded as
package tool, unpinned: the --from value was skipped as a flag value
and the command name was read as the package. So a different package
behind a familiar command name was invisible (uvx --from other-pkg==1.0 controlloop reported controlloop), and a version bump behind --from
scored medium (changed arguments) instead of high in
policy.mcp-server-identity-change.

  • The --from (uvx) or --spec (pipx run) requirement, when it comes
    before the command, is now the package. After the command it belongs to
    the tool and is ignored.
  • === pins and Git sources with a revision (git+https://host/repo@v1.2)
    count as pinned; the @ in git+ssh://git@host/... does not.
  • The launched requirement is no longer redacted as a KEY=value
    argument (pkg==1.2 was shown as pkg=<redacted>). Every other
    KEY=value argument still is, including TOKEN==secret.

Testing

  • tests/adapters/test_mcp_identity.py: 14 new parser cases and 4
    redaction cases. One existing case changes on purpose:
    --from git+x tool now records package git+x, not tool.
  • tests/policy/rules/test_mcp_server_identity_change.py: a version bump
    and a swapped package behind uvx --from are high. Both tests fail on
    the previous code (medium).
  • ruff format --check, ruff check, mypy, full pytest.

`uvx --from pkg==1.2 tool` was recorded as package `tool`, unpinned: the
`--from` value was skipped as a flag value and the command name read as
the package. A different package behind a familiar command name was
therefore invisible, and a version bump behind `--from` scored `medium`
(changed arguments) instead of `high` in policy.mcp-server-identity-change.

The `--from` (uvx) or `--spec` (pipx run) requirement, when it comes
before the command, is now the package. `===` pins and Git sources with a
revision are read as pinned. The requirement itself is no longer redacted
as a KEY=value argument (`pkg==1.2` was shown as `pkg=<redacted>`); other
KEY=value arguments still are.

Signed-off-by: controlloop-security <344908699+controlloop-security@users.noreply.github.com>
@controlloop-security
controlloop-security merged commit 27dc82a into main Oct 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant