feat: add ws-signaling-proxy reference implementation#92
Conversation
commit: |
| } | ||
|
|
||
| start() { | ||
| const url = `${this.config.decartBaseUrl}/v1/stream?api_key=${this.config.decartApiKey}&model=${this.config.model}`; |
There was a problem hiding this comment.
Unencoded model parameter enables URL injection
High Severity
The model value comes from client-supplied query parameters via URLSearchParams.get(), which returns the decoded value. It's then directly interpolated into the upstream URL string without encoding. A malicious client can inject arbitrary query parameters into the upstream Decart API request (e.g. ?model=x%26api_key=other) by embedding encoded ampersands. The model value needs to be passed through encodeURIComponent before interpolation.
Additional Locations (1)
| return code; | ||
| } | ||
| return 1000; | ||
| } |
There was a problem hiding this comment.
sanitizeCloseCode silently converts valid error codes to normal
Medium Severity
sanitizeCloseCode only allows code 1000 or >= 3000, but the ws library accepts 1000–1003, 1007–1014, and 3000–4999 as valid close codes. This means the explicit this.close(1011, "upstream connection error") on upstream failure is silently downgraded to 1000 (Normal Closure), so the client never learns the connection was closed due to an error. Additionally, valid forwarded codes like 1001 (Going Away) are lost. The condition also passes through codes >= 5000 which the ws library considers invalid and would throw a RangeError on.
Additional Locations (1)
| ); | ||
| this.close(code, reasonStr); | ||
| }); | ||
| } |
There was a problem hiding this comment.
Missing client WebSocket error handler crashes process
High Severity
The start() method attaches an "error" handler on this.upstream but not on this.clientWs. In Node.js, an EventEmitter that emits an "error" event with no listener throws the error as an uncaught exception, crashing the process. Any client-side network disruption (connection reset, broken pipe, etc.) would bring down the entire proxy for all connected users.


Summary
ws-signaling-proxypackage — a reference WebSocket signaling proxy for providers integrating with Decart's realtime APITest plan
cd ws-signaling-proxy && pnpm typecheck && pnpm lintDECART_API_KEY=... pnpm test:e2epnpm dev— connect from browser SDK and verify signaling flowNote
Medium Risk
Introduces a new server-side WebSocket proxy that handles API keys and bidirectional message forwarding; correctness and safe logging/close handling are important even though it’s added as an isolated, private package.
Overview
Adds a new
packages/ws-signaling-proxyreference service that terminates client WebSocket connections and opens an upstream Decart/v1/streamWebSocket using a server-sideDECART_API_KEY, forwarding frames bidirectionally (with buffering until upstream is ready) and propagating closes with sanitized close codes.Includes developer docs (
README.md,.env.example), TypeScript build/config and an e2e test that spins up the proxy and validatesset_image/promptround-trips against the Decart API. CI is updated to run build/lint/format/typecheck for this new package and the lockfile is updated for the added dependencies.Written by Cursor Bugbot for commit 34a8212. This will update automatically on new commits. Configure here.