Skip to content

fix(security): shadowing check needs clone evidence, not a name coincidence - #951

Merged
github-actions[bot] merged 3 commits into
mainfrom
fix/tpa-shadowing-name-coincidence
Aug 4, 2026
Merged

fix(security): shadowing check needs clone evidence, not a name coincidence#951
github-actions[bot] merged 3 commits into
mainfrom
fix/tpa-shadowing-name-coincidence

Conversation

@Dumbris

@Dumbris Dumbris commented Aug 4, 2026

Copy link
Copy Markdown
Member

Problem

Reported against v0.53.0-rc.7: the TPA scanner raised a dangerous / HIGH detect.shadowing.cross_server finding because ElevenLabs and Kaggle both expose list_models.

A name collision alone is mcpproxy's normal operating condition: the proxy exists to unify many servers, every tool is namespaced server:tool, and retrieve_tools' BM25 ranking is what disambiguates shared compound names (list_models, search_issues, …). The "distinctive name" length heuristic cannot separate those from attacks.

Change

  • Collision branch → impersonation-clone evidence required: fires only when the same name on another server comes with a near-duplicate description (deterministic token-set containment, both-direction thresholds; cosmetic case/punctuation/whitespace edits do not launder a copy). Bare name coincidences are silent from both sides — the empty-description case never matches.
  • Reference branch: no longer fires when the tool's own server also exposes the referenced name — "call list_models first" is ordinary self-documentation, whoever else exposes that name. Still requires a distinctive name and still ignores self-references.
  • Corpus (spec 065): the two sh_collide_* malicious entries modelled bare collisions with honestly different descriptions — the exact FP class — and now model the real clone attack; new hn_name_coincidence hard-negative encodes the ElevenLabs/Kaggle case as benign. Unicode escapes in the smuggling entries preserved byte-for-byte.
  • Scanner engine/adapter test fixtures updated to the clone shape; docs (tool-scanner.md, security-quarantine.md) describe the new semantics.

Tests

New: name-coincidence-with-distinct-descriptions is silent (both sides), cosmetic-edit clones still flag, own-server reference is silent. Full ./internal/security/... with -race, strict golangci-lint v2, and ./scripts/test-api-e2e.sh all green.

…idence

Owner report against v0.53.0-rc.7: the TPA scanner raised a dangerous
finding because ElevenLabs and kaggle both expose list_models. A name
collision alone is the proxy's normal operating condition — mcpproxy
unifies many servers, every tool is namespaced server:tool, and
retrieve_tools' BM25 ranking is what disambiguates shared compound
names. No fixed "distinctive name" heuristic separates those from
attacks.

- Collision branch now requires impersonation-clone evidence: the same
  name on another server AND a near-duplicate description (token-set
  containment; cosmetic case/punctuation/whitespace edits do not
  launder a copy). Bare coincidences are silent from both sides.
- Reference branch no longer fires when the tool's OWN server also
  exposes the referenced name — "call list_models first" is ordinary
  self-documentation, whoever else exposes that name.
- Corpus: the two shadowing entries now model the real clone attack
  (they were bare collisions with honestly different descriptions —
  the exact FP class); new hard-negative hn_name_coincidence encodes
  the ElevenLabs/kaggle case as benign. Unicode escapes preserved.
- Docs updated (tool-scanner.md, security-quarantine.md).
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: daacd68
Status: ✅  Deploy successful!
Preview URL: https://c90bc976.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-tpa-shadowing-name-coinc.mcpproxy-docs.pages.dev

View logs

… robustness

- cmd/scan-eval gateFixture and the sh_collide_transfer corpus entry
  modelled bare collisions (or byte-identical dups); both now model the
  cosmetic-variant clone the check actually detects, so the gate
  measures the real attack shape.
- hn_name_coincidence renamed hn_shadowing_name_coincidence per the
  corpus id-prefix convention (detect_corpus_test hardNegPrefix).
- descTokens is unicode-aware: a Cyrillic/CJK description tokenizes to
  real words instead of an empty set that could never evidence a clone.
- cloneDescriptions requires >=3 tokens per side: "Create" == "Create"
  carries no information, and sub-minimal identical descriptions no
  longer hard-flag a shared name.
- The two accepted trade-offs codex argued (different-description
  collisions out of scope; own-server decoy silencing the reference
  branch) are now documented at the decision sites: both reduce to the
  name-coincidence policy the owner set (MCP-3520), whose defenses are
  admission quarantine, server:tool namespacing, and retrieve_tools
  provenance — not a collision alarm.
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/tpa-shadowing-name-coincidence

Available Artifacts

  • archive-darwin-amd64 (28 MB)
  • archive-darwin-arm64 (26 MB)
  • archive-linux-amd64 (17 MB)
  • archive-linux-arm64 (15 MB)
  • archive-windows-amd64 (28 MB)
  • archive-windows-arm64 (25 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (22 MB)
  • installer-dmg-darwin-arm64 (20 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 30882676887 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

…codex round 2)

FieldsFunc finds no word boundaries in unspaced Han/kana/Hangul/Thai
text, so an informative CJK description collapsed to ONE token and
ducked under the three-token evidence floor — a cloned unspaced
description could never be detected, and the round-1 test had cheated
with artificial spaces. Runs in spaceless scripts now emit character
bigrams (the standard segmentation-free indexing unit), which restores
both the floor and the containment thresholds for those scripts. The
boundary itself is now pinned: two identical tokens carry no clone
evidence, three do.
@Dumbris

Dumbris commented Aug 4, 2026

Copy link
Copy Markdown
Member Author

Codex critic review — three rounds, final verdict CLEAN:

  • Round 1: found the two downstream fixture breaks (scan-eval gateFixture still modelling a bare collision; corpus hard-negative violating the hn_shadowing id-prefix rule) plus tokenizer robustness gaps (non-Latin scripts tokenized to nothing; no minimum-evidence floor). All fixed.
  • Round 2: caught that unspaced CJK text collapses to one FieldsFunc token and ducks the 3-token floor — and that the round-1 test had hidden it with artificial spaces. Fixed with character-bigram tokenization for spaceless scripts (Han/kana/Hangul/Thai); the 2-vs-3-token evidence boundary is now pinned by tests.
  • Round 3: CLEAN — verified the bigram containment arithmetic (13/13, 13/14 vs the 0.85/0.70 thresholds), the boundary tests, and the suites.

Codex also argued bare collisions remain "worth flagging"; that is the owner's explicit product decision going the other way (a colliding name with a different description is indistinguishable from ElevenLabs-vs-Kaggle list_models), and the accepted residual risk + compensating controls (admission quarantine, server:tool namespacing, retrieve_tools provenance) are documented at both decision sites.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved (Model B): codex critic clean after 3 rounds; qa-gate green; CI fully green.

@github-actions
github-actions Bot merged commit c2f2285 into main Aug 4, 2026
41 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.

2 participants