Skip to content

fix(server): guard JSON.parse in protocol message handlers#40756

Merged
pavelfeldman merged 2 commits into
microsoft:mainfrom
SebTardif:fix-json-parse-crash
May 10, 2026
Merged

fix(server): guard JSON.parse in protocol message handlers#40756
pavelfeldman merged 2 commits into
microsoft:mainfrom
SebTardif:fix-json-parse-crash

Conversation

@SebTardif
Copy link
Copy Markdown
Contributor

Summary

  • PlaywrightConnection and PipeTransport call JSON.parse on incoming messages without try-catch, unlike WebSocketTransport which already guards against this (chore: log when websockets are proactively closed #23689).
  • In PlaywrightConnection, the parse runs inside an async event handler. The rejected Promise is unhandled (no global unhandledRejection handler in the remote server), crashing the process. A single malformed WebSocket frame takes down all connected clients.
  • In PipeTransport, the parse runs inside a setImmediate callback, causing uncaughtException on corrupted browser output.
  • Wrap both in try-catch to match the existing WebSocketTransport pattern. PlaywrightConnection closes the offending connection with WebSocket code 1007; PipeTransport logs and skips the malformed message.

The PlaywrightConnection fix is the same approach from #40121 (approved by @pavelfeldman but not merged). This PR also covers PipeTransport.

The unguarded JSON.parse in PlaywrightConnection was introduced in #28141 (2023-11-16). In PipeTransport, it has been unguarded since #1567 (2020-03-26).

PlaywrightConnection and PipeTransport call JSON.parse on incoming
messages without try-catch. In PlaywrightConnection, the parse runs
inside an async event handler whose rejected Promise is unhandled,
crashing the server process. In PipeTransport, the parse runs inside
a setImmediate callback, causing an uncaughtException.

Wrap both in try-catch to match the existing pattern in
WebSocketTransport (added in microsoft#23689).

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
this._waitForNextTask(() => {
let parsedMessage;
try {
parsedMessage = JSON.parse(message);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(meaning keep crashing on invalid pipe data)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, reverted the pipeTransport changes. The guard now only covers PlaywrightConnection (untrusted remote clients).

PipeTransport talks to a local browser process over stdio.
If the browser sends malformed JSON, the situation is
unrecoverable; crashing is the correct behavior.

Keep the guard only in PlaywrightConnection, which handles
untrusted remote WebSocket clients.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 9, 2026

Test results for "MCP"

7 failed
❌ [firefox] › mcp/annotate.spec.ts:173 › user-initiated annotate downloads zip with feedback.md @mcp-ubuntu-latest-firefox
❌ [firefox] › mcp/annotate.spec.ts:367 › should cancel browser_annotate when the MCP request is aborted @mcp-windows-latest-firefox
❌ [firefox] › mcp/annotate.spec.ts:398 › should cancel browser_annotate when the MCP client disconnects @mcp-windows-latest-firefox
❌ [firefox] › mcp/annotate.spec.ts:427 › should switch screencast to -s session on show --annotate @mcp-windows-latest-firefox
❌ [firefox] › mcp/annotate.spec.ts:476 › should disengage annotate mode when --annotate client disconnects @mcp-windows-latest-firefox
❌ [firefox] › mcp/cli-devtools.spec.ts:217 › video-start-stop @mcp-windows-latest-firefox
❌ [firefox] › mcp/cli-devtools.spec.ts:231 › video-chapter @mcp-windows-latest-firefox

7050 passed, 1068 skipped


Merge workflow run.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 9, 2026

Test results for "tests 1"

2 flaky ⚠️ [chromium-library] › library/popup.spec.ts:261 › should not throw when click closes popup `@chromium-ubuntu-22.04-node20`
⚠️ [firefox-page] › page/page-emulate-media.spec.ts:144 › should keep reduced motion and color emulation after reload `@firefox-ubuntu-22.04-node20`

41718 passed, 850 skipped


Merge workflow run.

@pavelfeldman pavelfeldman merged commit cb3312b into microsoft:main May 10, 2026
43 of 45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants