fix: log the rejected progressToken's type, not its value

The warning added one commit earlier echoed the rejected value. That is the
same leak class as the `servers/show` fix: `_meta` now carries arbitrary JSON,
so an invalid `progressToken` can be an object holding credentials — and this
logger is persisted by real clients (`clients/tui/src/logger.ts` writes it to
`~/.mcp-inspector/auth.log` via `pino.destination`, append mode).

Log `{ received: describeJsonType(value) }` instead — "object", "array",
"number". That is what makes the warning actionable; the value itself only
leaks.

Test asserts the record is exactly `{ received: "object" }` and that the
planted secret appears nowhere in the captured calls.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177mPHAdECD18nLLCTwR5rh
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-23 14:19:48 -04:00
commit ae9536b171

View file

@ -369,6 +369,16 @@ interface ToolCallRequest {
// server can't spin a tight zero-delay loop; a successful acknowledgement resets
// the count, and past the cap we give up (mark the stream ended) rather than
// retry a persistently-failing re-list forever.
/**
* A one-word name for a JSON value's type, for diagnostics that must not
* disclose the value itself.
*/
function describeJsonType(value: unknown): string {
if (value === null) return "null";
if (Array.isArray(value)) return "array";
return typeof value;
}
/**
* Whether a `_meta.progressToken` value is one the protocol allows.
*
@ -1078,8 +1088,13 @@ export class InspectorClient extends InspectorClientEventTarget {
// the request stays well-formed and simply asks for no progress. Warn,
// because a silently dropped key the user typed is worse than a noisy one.
if ("progressToken" in merged && !isProgressToken(merged.progressToken)) {
// Log the rejected value's *type*, never the value. `_meta` now carries
// arbitrary JSON, so an invalid `progressToken` can be an object holding
// credentials — and this logger is persisted by real clients (the TUI
// writes it to `~/.mcp-inspector/auth.log`). The type is what makes the
// warning actionable anyway; the value would only leak.
this.logger.warn(
{ progressToken: merged.progressToken },
{ received: describeJsonType(merged.progressToken) },
"Dropping `_meta.progressToken` — expected a string or an integer.",
);
delete merged.progressToken;