#2429·inspector

Deep-link auth-token comparison in deepLink.ts isn't constant-time

Author: CloneOfAlexCreated Sep 18, 2026Updated Sep 18, 2026
Labelsbugv2

Which version line?

v2 — current (@modelcontextprotocol/inspector@latest)

Which client?

Web

Inspector version

2.7.0 (git tag) — static code-review finding, not run locally

Node version

N/A — static code review, no live run performed

Operating system (and browser, for the web client)

N/A — static code review

Transport

Not applicable / never connected

MCP server under inspection

N/A — this is a static code-review finding against the 2.7.0 tag's clients/web/src/utils/deepLink.ts, not a live reproduction against a running MCP server.

Steps to reproduce

Found via static review of the 2.7.0 tag source, not a live run.

  1. clients/web/src/utils/deepLink.ts's parseDeepLink() reads an authToken from the app's own config and a token from the incoming deep-link URL's query params, then compares them with plain !==/===: if (!authToken || autoConnect !== authToken) return undefined; and const autoOpen = params.get("autoOpen") === authToken;.
  2. JavaScript's === on strings short-circuits at the first differing character, so comparison time leaks (very slightly, but measurably in principle) how many leading characters of a guessed token are correct.
  3. This is the same class of issue the project has hardened elsewhere for security-sensitive comparisons (e.g. its documented care around loopback/CIMD checks); a CSRF-style deep-link token comparison is a plausible candidate for the same treatment, since a local attacker (another process, another browser tab) may be able to trigger repeated deep-link opens and time the responses. No live timing attack was attempted; this is based on reading deepLink.ts against the 2.7.0 tag.

Expected behavior

The deep-link auth-token comparison in parseDeepLink() uses a constant-time comparison (e.g. a timing-safe-equal helper), the same way other security-sensitive token/credential comparisons in the codebase are expected to be handled, so response timing cannot leak how much of a guessed token was correct.

Actual behavior

parseDeepLink() compares the deep-link's autoConnect/autoOpen params against the configured authToken using plain !==/===, which short-circuits on the first mismatched character and so is not constant-time. It's a narrow, largely theoretical local-attacker timing side channel, but it's the kind of comparison this project has otherwise been careful to harden (loopback/CIMD checks, etc.).

Suggested fix: replace the plain string comparison with a constant-time comparison (e.g. compare fixed-length HMACs or use a timing-safe-equal utility) for the authToken check in parseDeepLink().

Logs, errors, or screenshots

No response

Already prototyped a fix?

No response

Before you submit

  • I searched existing issues and this is not a duplicate.
  • This is not a security vulnerability report (those go through the private advisory process).

Source: modelcontextprotocol/inspector