Deep-link auth-token comparison in deepLink.ts isn't constant-time
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.
- clients/web/src/utils/deepLink.ts's parseDeepLink() reads an
authTokenfrom 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;andconst autoOpen = params.get("autoOpen") === authToken;. - 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. - 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