Skip to content

Commit cb3312b

Browse files
authored
fix(server): guard JSON.parse in protocol message handlers (microsoft#40756)
1 parent 5327da1 commit cb3312b

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

packages/playwright-core/src/remote/playwrightConnection.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,14 @@ export class PlaywrightConnection {
6464
transport.on('message', async (message: string) => {
6565
await lock;
6666
const messageString = Buffer.from(message).toString();
67-
const jsonMessage = JSON.parse(messageString);
67+
let jsonMessage: any;
68+
try {
69+
jsonMessage = JSON.parse(messageString);
70+
} catch (e) {
71+
debugLogger.log('server', `[${this._id}] failed to parse message: ${e}`);
72+
this.close({ code: 1007, reason: 'Malformed message' });
73+
return;
74+
}
6875
if (debugLogger.isEnabled('server:channel'))
6976
debugLogger.log('server:channel', `[${this._id}] ${monotonicTime() * 1000} ◀ RECV ${messageString}`);
7077
if (debugLogger.isEnabled('server:metadata'))

tests/library/browsertype-connect.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,22 @@ for (const kind of ['launchServer', 'run-server'] as const) {
158158
}
159159
});
160160

161+
test('should not crash on malformed json frame', async ({ connect, startRemoteServer }) => {
162+
const remoteServer = await startRemoteServer(kind);
163+
const ws = new WebSocket(remoteServer.wsEndpoint());
164+
await new Promise<void>((resolve, reject) => {
165+
ws.once('open', resolve);
166+
ws.once('error', reject);
167+
});
168+
ws.send(']');
169+
await new Promise<void>(resolve => ws.once('close', () => resolve()));
170+
// Server should still be alive and accept new connections.
171+
const browser = await connect(remoteServer.wsEndpoint());
172+
const page = await browser.newPage();
173+
expect(await page.evaluate('1 + 2')).toBe(3);
174+
await browser.close();
175+
});
176+
161177
test('should be able to visit ipv6', async ({ connect, startRemoteServer, ipV6ServerPort, channel }) => {
162178
test.fail(!!process.env.INSIDE_DOCKER, 'docker does not support IPv6 by default');
163179
test.fail(channel === 'webkit-wsl', 'WebKit on WSL does not support IPv6: https://github.com/microsoft/WSL/issues/10803');

0 commit comments

Comments
 (0)