Repository navigation
Conversation
The JSON reader does not validate UTF-8 inside string tokens. That only happens when a token is converted to a .NET string, which throws InvalidOperationException. Converting a non-string value to a string throws the same exception. HandlePostRequestAsync only catches JsonException, so these requests returned 500. Read these values with a helper that returns false instead of throwing, and reject them with the error each check already uses: - initialize params.protocolVersion: 400, HeaderMismatch (-32020) - _meta protocolVersion: treated as missing, 400, InvalidParams (-32602) - Mcp-Name body value (invalid UTF-8 or not a string): 400, HeaderMismatch - x-mcp-header argument values: 400, HeaderMismatch All responses echo the request id. Fixes modelcontextprotocol#1984
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1984
Problem
HandlePostRequestAsyncreads some request values as strings while it validates the headers against the body. Two kinds of input make those reads throwInvalidOperationException, which the handler does not catch (it only catchesJsonException), so the request returns 500:Utf8JsonReaderaccepts the bytes inside a string token and only validates them when the token is converted to a .NET string."name": 5on atools/callrequest.JsonValue.GetValue<string>()throws for it.Affected reads:
params.protocolVersiononinitialize(with anMCP-Protocol-Versionheader)HeaderMismatch(-32020)_meta/io.modelcontextprotocol/protocolVersionInvalidParams(-32602)Mcp-Name(invalid UTF-8 or not a string)ValidateMcpHeadersHeaderMismatch(-32020)x-mcp-headerValidateCustomParamHeadersHeaderMismatch(-32020)Change
TryGetStringValuehelper that returnsfalseinstead of throwing when a node is not a JSON string or the string is not valid UTF-8, and aTryGetJsonNodeStringPropertywrapper that replacesGetJsonNodeStringProperty._metaprotocol version is handled like a missing one, the same as a non-string value today.McpHeaderEncoderis unchanged. Thex-mcp-headercheck validates the argument before callingConvertToHeaderValue.On the question in the issue (-32600 vs -32700): the body is well-formed JSON and is parsed into a valid JSON-RPC request with a readable id, so I used the codes each validation step already returns. Happy to switch to a different code if you prefer.
Tests
Five tests in
HttpHeaderConformanceTests. Each one failed with 500 before the change. Each now checks the status, the JSON-RPC error code, and the echoed id:Server_RejectsInvalidUtf8InProtocolVersionMeta_WithBadRequestServer_RejectsInvalidUtf8InInitializeProtocolVersion_WithBadRequestServer_RejectsInvalidUtf8InMcpNameBodyValue_WithBadRequestServer_RejectsInvalidUtf8InCustomParamHeaderArgument_WithBadRequestServer_RejectsNonStringMcpNameBodyValue_WithBadRequestLocal results:
ModelContextProtocol.AspNetCore.Tests(net10.0): 759 passed, 0 failed, 45 skippedModelContextProtocol.Tests(net472): 3299 passed, 0 failed, 290 skippedNote
This PR was written with help from an AI coding assistant (Claude Code). I reviewed the change, reproduced the bug, and ran the build and tests locally.