MCPcopy Create free account
hub / github.com/getsentry/sentry-javascript / handleTunnelRequest

Function handleTunnelRequest

packages/core/src/utils/tunnel.ts:21–76  ·  view source on GitHub ↗
(options: HandleTunnelRequestOptions)

Source from the content-addressed store, hash-verified

19 * @returns A `Response` — either the upstream Sentry response on success, or an error response.
20 */
21export async function handleTunnelRequest(options: HandleTunnelRequestOptions): Promise<Response> {
22 const { request, allowedDsns } = options;
23
24 if (allowedDsns.length === 0) {
25 return new Response('Tunnel not configured', { status: 500 });
26 }
27
28 const body = new Uint8Array(await request.arrayBuffer());
29
30 let envelopeHeader;
31 try {
32 [envelopeHeader] = parseEnvelope(body);
33 } catch {
34 return new Response('Invalid envelope', { status: 400 });
35 }
36
37 if (!envelopeHeader) {
38 return new Response('Invalid envelope: missing header', { status: 400 });
39 }
40
41 const dsn = envelopeHeader.dsn;
42 if (!dsn) {
43 return new Response('Invalid envelope: missing DSN', { status: 400 });
44 }
45
46 // SECURITY: Validate that the envelope DSN matches one of the allowed DSNs
47 // This prevents SSRF attacks where attackers send crafted envelopes
48 // with malicious DSNs pointing to arbitrary hosts
49 const isAllowed = allowedDsns.some(allowed => allowed === dsn);
50
51 if (!isAllowed) {
52 debug.warn(`Sentry tunnel: rejected request with unauthorized DSN (${dsn})`);
53 return new Response('DSN not allowed', { status: 403 });
54 }
55
56 const dsnComponents = makeDsn(dsn);
57 if (!dsnComponents) {
58 debug.warn(`Could not extract DSN Components from: ${dsn}`);
59 return new Response('Invalid DSN', { status: 403 });
60 }
61
62 const sentryIngestUrl = getEnvelopeEndpointWithUrlEncodedAuth(dsnComponents);
63
64 try {
65 return await fetch(sentryIngestUrl, {
66 method: 'POST',
67 headers: {
68 'Content-Type': 'application/x-sentry-envelope',
69 },
70 body,
71 });
72 } catch (error) {
73 debug.error('Sentry tunnel: failed to forward envelope', error);
74 return new Response('Failed to forward envelope to Sentry', { status: 500 });
75 }
76}

Callers 2

tunnel.test.tsFile · 0.90
createSentryTunnelRouteFunction · 0.90

Calls 7

parseEnvelopeFunction · 0.90
makeDsnFunction · 0.90
arrayBufferMethod · 0.65
warnMethod · 0.65
errorMethod · 0.65
fetchFunction · 0.50

Tested by

no test coverage detected