[Server] Handle malformed JSON-RPC input graceful - #412
Open
chr-hertel wants to merge 3 commits into
Open
Conversation
chr-hertel
requested review from
CodeWithKyrian,
Nyholm and
soyuka
as code owners
August 10, 2026 21:58
chr-hertel
force-pushed
the
fix/malformed-input-hardening
branch
2 times, most recently
from
August 10, 2026 22:22
c3fbec1 to
60208a4
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Hardens server-side JSON-RPC processing against malformed payloads and unexpected PHP throwables.
Changes:
- Adds protocol-level exception containment and generic internal errors.
- Validates schema payload types during hydration.
- Expands malformed-input and exception-handling tests.
Reviewed changes
Copilot reviewed 50 out of 50 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/JsonRpc/MessageFactory.php |
Validates JSON-RPC method types. |
src/Server/Protocol.php |
Contains unexpected processing failures. |
src/Schema/Annotations.php |
Validates annotation payloads. |
src/Schema/Content/AudioContent.php |
Validates audio fields and annotations. |
src/Schema/Content/BlobResourceContents.php |
Validates optional blob metadata. |
src/Schema/Content/EmbeddedResource.php |
Safely hydrates annotations. |
src/Schema/Content/PromptMessage.php |
Validates content types and roles. |
src/Schema/Content/SamplingMessage.php |
Validates content types and roles. |
src/Schema/Content/TextContent.php |
Safely hydrates annotations. |
src/Schema/Content/TextResourceContents.php |
Validates optional text metadata. |
src/Schema/Elicitation/ElicitationSchema.php |
Validates required-property lists. |
src/Schema/Extension/Apps/UiResourceContentMeta.php |
Validates UI resource metadata. |
src/Schema/Extension/Apps/UiResourceCsp.php |
Validates CSP containers. |
src/Schema/Extension/Apps/UiToolMeta.php |
Validates UI tool metadata. |
src/Schema/Icon.php |
Adds safe icon-list hydration. |
src/Schema/Implementation.php |
Validates implementation metadata. |
src/Schema/ModelPreferences.php |
Validates model preferences. |
src/Schema/Notification/CancelledNotification.php |
Validates cancellation reasons. |
src/Schema/Notification/LoggingMessageNotification.php |
Validates logging fields and levels. |
src/Schema/Notification/ProgressNotification.php |
Validates numeric progress fields. |
src/Schema/Prompt.php |
Safely hydrates arguments and icons. |
src/Schema/PromptArgument.php |
Validates optional argument fields. |
src/Schema/Request/CompletionCompleteRequest.php |
Validates completion references. |
src/Schema/Request/CreateSamplingMessageRequest.php |
Validates sampling parameters. |
src/Schema/Request/InitializeRequest.php |
Validates initialization parameters. |
src/Schema/Request/ListPromptsRequest.php |
Validates prompt cursor. |
src/Schema/Request/ListResourcesRequest.php |
Validates resource cursor. |
src/Schema/Request/ListResourceTemplatesRequest.php |
Validates template cursor. |
src/Schema/Request/ListToolsRequest.php |
Validates tool cursor. |
src/Schema/Request/SetLogLevelRequest.php |
Safely validates logging levels. |
src/Schema/ResourceDefinition.php |
Validates resource metadata and icons. |
src/Schema/ResourceTemplate.php |
Validates template metadata. |
src/Schema/Result/CallToolResult.php |
Validates tool result fields. |
src/Schema/Result/CompletionCompleteResult.php |
Validates completion result fields. |
src/Schema/Result/CreateSamplingMessageResult.php |
Safely validates result roles. |
src/Schema/Result/ElicitResult.php |
Safely validates elicitation actions. |
src/Schema/Result/GetPromptResult.php |
Validates prompt result messages. |
src/Schema/Result/InitializeResult.php |
Validates initialization result metadata. |
src/Schema/Result/ListPromptsResult.php |
Validates prompt lists and cursors. |
src/Schema/Result/ListResourcesResult.php |
Validates resource lists and cursors. |
src/Schema/Result/ListResourceTemplatesResult.php |
Validates template lists and cursors. |
src/Schema/Result/ListToolsResult.php |
Validates tool lists and cursors. |
src/Schema/Root.php |
Validates optional root names. |
src/Schema/Tool.php |
Uses safe icon-list hydration. |
src/Schema/ToolAnnotations.php |
Validates tool annotation fields. |
tests/Unit/Fixtures/ThrowingRequest.php |
Provides throwable-producing fixture. |
tests/Unit/JsonRpc/MalformedInputTest.php |
Covers malformed payload hydration. |
tests/Unit/JsonRpc/MessageFactoryTest.php |
Covers invalid method types and batches. |
tests/Unit/Schema/Result/ElicitResultTest.php |
Updates invalid-action expectations. |
tests/Unit/Server/ProtocolTest.php |
Covers containment and message redaction. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // Last line of defense: a malformed message must never escape as a PHP error and take the | ||
| // server process down. | ||
| try { | ||
| $this->doProcessInput($transport, $input, $sessionId); |
Member
Author
There was a problem hiding this comment.
Taking this as known issue
Comment on lines
+66
to
+68
| if (isset($preferences['hints']) && !\is_array($preferences['hints'])) { | ||
| throw new InvalidArgumentException('Invalid "hints" in ModelPreferences data.'); | ||
| } |
chr-hertel
force-pushed
the
fix/malformed-input-hardening
branch
from
August 10, 2026 23:50
60208a4 to
07c6e0d
Compare
chr-hertel
force-pushed
the
fix/malformed-input-hardening
branch
from
August 10, 2026 23:59
07c6e0d to
e44dcf9
Compare
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.
Malformed input could fail with a PHP
TypeError/ValueErrorinstead of anInvalidInputMessageException. Those escape every catch on the way out —MessageFactory,Protocol::processInput(),BaseTransport::handleMessage()andServer::run()— so the peer got a dead process instead of a JSON-RPC error.Protocol::processInput()never lets a throwable escape, reporting anything unexpected as-32603, and guards each message of a batch on its own.-32600instead of a PHP error.-32603reply, matching what the tool, prompt, resource and completion handlers already do.Reported by @nickelsec.