Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix(tunnel): handle malformed envelope JSON with 400 response
Wrap parseEnvelope in try-catch so malformed request bodies return a
400 Bad Request instead of throwing an unhandled error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
  • Loading branch information
nikolovlazar and claude committed Feb 18, 2026
commit ecda7c2089fb07b49965562ed4ece6a452f5fef2
8 changes: 7 additions & 1 deletion packages/core/src/utils/tunnel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ export async function handleTunnelRequest(options: HandleTunnelRequestOptions):

const body = new Uint8Array(await request.arrayBuffer());

const [envelopeHeader] = parseEnvelope(body);
let envelopeHeader;
try {
[envelopeHeader] = parseEnvelope(body);
} catch {
return new Response('Invalid envelope', { status: 400 });
}

if (!envelopeHeader) {
return new Response('Invalid envelope: missing header', { status: 400 });
}
Comment thread
cursor[bot] marked this conversation as resolved.
Expand Down
12 changes: 12 additions & 0 deletions packages/core/test/lib/utils/tunnel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ describe('handleTunnelRequest', () => {
expect(fetchMock).not.toHaveBeenCalled();
});

it('returns 400 when the envelope body contains malformed JSON', async () => {
const result = await handleTunnelRequest({
request: new Request('http://localhost/tunnel', { method: 'POST', body: 'not valid envelope data{{{' }),
allowedDsns: [TEST_DSN],
});

expect(result).toBeInstanceOf(Response);
expect(result.status).toBe(400);
expect(await result.text()).toBe('Invalid envelope');
expect(fetchMock).not.toHaveBeenCalled();
});

it('returns 403 when the envelope DSN is not in allowedDsns', async () => {
const result = await handleTunnelRequest({
request: makeEnvelopeRequest({ dsn: 'https://other@example.com/9999' }),
Expand Down
Loading