diff --git a/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs b/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs index 9366063e4..904f4db00 100644 --- a/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs +++ b/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs @@ -126,7 +126,8 @@ public static class McpHeaderEncoder // Check for Base64 wrapper. The spec requires the sentinel markers to be // case-sensitive and exactly lowercase per SEP-2243. - if (headerValue.StartsWith(Base64Prefix, StringComparison.Ordinal) && + if (headerValue.Length >= Base64Prefix.Length + Base64Suffix.Length && + headerValue.StartsWith(Base64Prefix, StringComparison.Ordinal) && headerValue.EndsWith(Base64Suffix, StringComparison.Ordinal)) { var base64Content = headerValue.Substring( diff --git a/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs b/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs index 26de71b45..1e4fc00ef 100644 --- a/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs +++ b/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs @@ -104,6 +104,16 @@ public void DecodeValue_ValidBase64_Decodes() Assert.Equal("Hello", result); } + [Fact] + public void DecodeValue_DegenerateWrapper_ReturnsLiteralValue() + { + // "=?base64?=" matches both the prefix "=?base64?" and the suffix "?=" because they + // overlap on the shared '?', but it is too short to contain any base64 content. It must be + // returned as-is rather than throwing when the wrapper is stripped. + var result = McpHeaderEncoder.DecodeValue("=?base64?="); + Assert.Equal("=?base64?=", result); + } + [Fact] public void DecodeValue_CaseSensitivePrefix_ReturnsLiteralValue() {