Skip to content

Commit c9327cd

Browse files
halter73Copilot
andcommitted
Reject mismatched initialize protocol versions
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 4aade88 commit c9327cd

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

‎src/ModelContextProtocol.AspNetCore/StreamableHttpHandler.cs‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,8 @@ private static string[] GetConfiguredSupportedProtocolVersions(string? protocolV
704704
}
705705

706706
/// <summary>
707-
/// Validates that HTTP requests using per-request metadata declare the same protocol version in both
708-
/// the <c>MCP-Protocol-Version</c> header and body <c>_meta</c> envelope.
707+
/// Validates that HTTP requests declare matching protocol versions in the
708+
/// <c>MCP-Protocol-Version</c> header and the corresponding body field.
709709
/// </summary>
710710
private static bool ValidateProtocolVersionEnvelope(
711711
HttpContext context,
@@ -719,6 +719,18 @@ private static bool ValidateProtocolVersionEnvelope(
719719
}
720720

721721
var protocolVersionHeader = context.Request.Headers[McpProtocolVersionHeaderName].ToString();
722+
723+
if (message is JsonRpcRequest { Method: RequestMethods.Initialize, Params: JsonObject initializeParams } &&
724+
initializeParams["protocolVersion"] is JsonValue initializeProtocolVersionValue &&
725+
initializeProtocolVersionValue.TryGetValue(out string? initializeProtocolVersion) &&
726+
!string.IsNullOrEmpty(protocolVersionHeader) &&
727+
!string.Equals(protocolVersionHeader, initializeProtocolVersion, StringComparison.Ordinal))
728+
{
729+
errorDetail = CreateHeaderMismatchError(
730+
$"Bad Request: The {McpProtocolVersionHeaderName} header value '{protocolVersionHeader}' does not match body params.protocolVersion value '{initializeProtocolVersion}'.");
731+
return false;
732+
}
733+
722734
bool hasProtocolVersionMeta = TryGetProtocolVersionMeta(message, out var protocolVersionMeta);
723735

724736
if (!McpProtocolVersions.RequiresPerRequestMetadata(protocolVersionHeader) &&

‎tests/ModelContextProtocol.AspNetCore.Tests/StreamableHttpServerConformanceTests.cs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,31 @@ public async Task PostRequest_Succeeds_WithValidProtocolVersionHeader()
204204
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
205205
}
206206

207+
[Theory]
208+
[InlineData(false, McpProtocolVersions.March2025ProtocolVersion, McpProtocolVersions.November2025ProtocolVersion)]
209+
[InlineData(false, McpProtocolVersions.November2025ProtocolVersion, McpProtocolVersions.March2025ProtocolVersion)]
210+
[InlineData(true, McpProtocolVersions.March2025ProtocolVersion, McpProtocolVersions.November2025ProtocolVersion)]
211+
[InlineData(true, McpProtocolVersions.November2025ProtocolVersion, McpProtocolVersions.March2025ProtocolVersion)]
212+
public async Task InitializeRequest_IsBadRequest_WhenProtocolVersionHeaderDoesNotMatchBody(
213+
bool stateless,
214+
string protocolVersionHeader,
215+
string protocolVersionBody)
216+
{
217+
await StartAsync(stateless);
218+
219+
var body = $$$$"""
220+
{"jsonrpc":"2.0","id":4242,"method":"initialize","params":{"protocolVersion":"{{{{protocolVersionBody}}}}","capabilities":{},"clientInfo":{"name":"IntegrationTestClient","version":"1.0.0"}}}
221+
""";
222+
using var request = new HttpRequestMessage(HttpMethod.Post, "") { Content = JsonContent(body) };
223+
request.Headers.Add("MCP-Protocol-Version", protocolVersionHeader);
224+
using var response = await HttpClient.SendAsync(request, TestContext.Current.CancellationToken);
225+
226+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
227+
var json = JsonNode.Parse(await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken));
228+
Assert.Equal(4242, json!["id"]!.GetValue<long>());
229+
Assert.Equal((int)McpErrorCode.HeaderMismatch, json["error"]!["code"]!.GetValue<int>());
230+
}
231+
207232
[Fact]
208233
public async Task GetRequest_IsBadRequest_WithInvalidProtocolVersionHeader()
209234
{

0 commit comments

Comments
 (0)