Skip to content

fix(coding-agent): resolve Smithery endpoints and key from trusted env - #3286

Merged
Yeachan-Heo merged 1 commit into
Yeachan-Heo:devfrom
10kH:fix/smithery-env-trust
Jul 27, 2026
Merged

fix(coding-agent): resolve Smithery endpoints and key from trusted env#3286
Yeachan-Heo merged 1 commit into
Yeachan-Heo:devfrom
10kH:fix/smithery-env-trust

Conversation

@10kH

@10kH 10kH commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Same trust-boundary class as #3262 / #3270 / #3276 / #3282, applied to the Smithery MCP registry.

Problem

site read role
smithery-auth.ts:7 SMITHERY_URL serves POST /api/auth/cli/session (:39) and the verification URL the user is sent to
smithery-connect.ts:1 SMITHERY_API_URL base every request carries Authorization: Bearer <apiKey> to (:42), and whose /connect/<namespace> routes return the SmitheryConnection records the agent consumes (:109)
smithery-auth.ts:65 SMITHERY_API_KEY that credential

Bun.env === process.env, and the env module folds the caller's cwd/.env into it, so repository content could drive the login flow, receive the API key, and supply the connection records.

Measured on this source with a project .env as the only input (HOME and agent dir kept neutral):

before: {"url":"https://attacker.example","apiKey":"attacker-key","apiBaseUrl":"https://attacker.example/api"}
after:  {"url":"https://smithery.ai","apiKey":null,"apiBaseUrl":"https://api.smithery.ai"}

Fix

All three resolve through $credentialEnv. Stored credentials (smithery.json), config, and shell / ~/.env / GJC-owned .env configuration are unchanged — verified in the same shape: an inherited SMITHERY_URL=https://smithery.internal with SMITHERY_API_KEY=operator-key still resolves.

Tests

smithery-env-trust.test.ts spawns a probe with a controlled cwd and neutral HOME and GJC_CODING_AGENT_DIR, so the other trusted file sources cannot leak in (the hermeticity point from your #3273 review, applied from the start here). Cases: built-in endpoints and no key by default, planted endpoints ignored, planted key ignored, inherited configuration honored, planted .env cannot override it.

Proof-first: reverting only the connect base fails ignores Smithery endpoints planted by the project .env (4 pass / 1 fail).

Verification

bun run check in packages/coding-agent (whole-package biome + tsc): exit 0. New suite: 5 pass / 0 fail. Smithery-named suites: 349 pass / 0 fail. MCP-named suites: 417 pass / 0 fail.

The probe imports the modules by relative path because ./runtime-mcp/* is intentionally null in the package exports map.

Three reads went through the merged view that includes the caller's cwd/.env:

  smithery-auth.ts:7     SMITHERY_URL      CLI auth session + user-facing
                                           verification URL (:39)
  smithery-auth.ts:65    SMITHERY_API_KEY  the API credential
  smithery-connect.ts:1  SMITHERY_API_URL  base for every request carrying
                                           Authorization: Bearer <apiKey> (:42)
                                           and for the /connect routes that
                                           return connection records (:109)

So repository content could drive the login flow, receive the key, and supply
the connection records the agent consumes.

All three resolve through $credentialEnv. Stored credentials, config and shell
configuration are unchanged.

Regression: a child process with a controlled cwd and neutral HOME/agent dir
proves planted endpoints and a planted key are ignored, inherited configuration
still applies, and a planted .env cannot override it. Reverting only the connect
base fails the planted-endpoint case.

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Verdict: APPROVE — exact head 90e52c9c1a76a688c5de5484c1d6423fe83df0e3

All three Smithery reads (SMITHERY_URL, SMITHERY_API_URL, SMITHERY_API_KEY) move from process.env/merged view to $credentialEnv, correctly scoped: origin drives the CLI auth session/verification URL, the API base receives the bearer key on every call, and the key is the credential itself.

Checks performed:

  • Trust-source precedence: verified against env.ts$credentialEnv excludes the project .env and honors launching-shell/GJC-owned file sources; matches the same rule validated in #3285.
  • Hardcoded endpoint severity: the https://smithery.ai / https://api.smithery.ai fallbacks are legitimate first-party defaults used only when no trusted override is set, not an attacker-controllable path — no severity concern.
  • Overlap/order: this PR's CHANGELOG.md insertion in packages/coding-agent lands at the same anchor (@@ -6,6 +6,7 @@, after the "Overflow maintenance…" line) as #3287 and #3288 — a trivial three-way additive conflict on merge order, not a correctness issue, but worth sequencing awareness since all three are open concurrently.
  • Tests: hermetic — both HOME and GJC_CODING_AGENT_DIR are pointed at temp dirs in resolveIn(), keeping every other trusted file source neutral (the gap #3284 fixed elsewhere is not present here). Covers default endpoints, project-.env-planted rejection (all three vars), inherited-honored, and project-cannot-override-inherited — matches the pattern established in #3285.
  • CI: all 20 checks pass on the exact head.
  • Novelty: no other open PR touches smithery-auth.ts/smithery-connect.ts; not a duplicate.
  • No automated reviewer comments present.

No merge action taken — post-#3281 dev CI 30253189244 is nonterminal and this batch is read-only review only.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo merged commit fa2ca8a into Yeachan-Heo:dev Jul 27, 2026
20 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