Title: [Security][Medium] WebSocket endpoint: no origin check, no maxPayload, unvalidated view_request params (server-side ReDoS via glob patterns)
Severity: Medium (CWE-346, CWE-400, CWE-1333)
Locations: packages/server/src/ws.ts:41-61; packages/core/src/view.ts:258-292 (globToRegex / computeView)
Summary
setupWebSocket creates the WSS with no origin/verifyClient check and no maxPayload; inbound messages are JSON.parse(raw.toString()) cast to {type, params?} with no schema. Attacker-controlled params (hiddenPaths, excludePatterns, scopeFiles) are stored per connection and compiled to regexes by globToRegex on every computeView — for all connected clients on every view snapshot.
Evidence
packages/server/src/ws.ts:41,53-60:
wss = new WebSocketServer({ server, path: '/ws' })
...
const msg = JSON.parse(raw.toString()) as { type: string; params?: ViewParams }
if (msg.type === 'view_request' && msg.params) {
const newParams = msg.params
clientParams.set(ws, newParams)
packages/core/src/view.ts — globToRegex escapes most specials but the result is unanchored and joins on .*:
const regexStr = trimmed.split('*').map((part) => part.replace(/[.+^${}()|[\]\\]/g, '\\$&')).join('.*')
return new RegExp(regexStr, 'i')
Patterns like a*a*a*a*a*...b produce classic nested-quantifier backtracking blowups, evaluated server-side on shared snapshots.
Impact
Any website can open a cross-origin WebSocket to ws://localhost:3357/ws (browser WebSocket is not subject to CORS) and (a) receive project snapshots, (b) submit params that trigger server-side CPU blowups affecting all connected clients.
Recommended fix
new WebSocketServer({ server, path: '/ws', maxPayload: 1<<20, verifyClient: originCheck }) (or token subprotocol); validate params with a zod schema; anchor/validate glob patterns before regex compilation (and consider a bounded matcher instead of RegExp).
Title: [Security][Medium] WebSocket endpoint: no origin check, no maxPayload, unvalidated view_request params (server-side ReDoS via glob patterns)
Severity: Medium (CWE-346, CWE-400, CWE-1333)
Locations: packages/server/src/ws.ts:41-61; packages/core/src/view.ts:258-292 (globToRegex / computeView)
Summary
setupWebSocketcreates the WSS with noorigin/verifyClientcheck and nomaxPayload; inbound messages areJSON.parse(raw.toString())cast to{type, params?}with no schema. Attacker-controlledparams(hiddenPaths, excludePatterns, scopeFiles) are stored per connection and compiled to regexes byglobToRegexon everycomputeView— for all connected clients on every view snapshot.Evidence
packages/server/src/ws.ts:41,53-60:
packages/core/src/view.ts — globToRegex escapes most specials but the result is unanchored and joins on
.*:Patterns like
a*a*a*a*a*...bproduce classic nested-quantifier backtracking blowups, evaluated server-side on shared snapshots.Impact
Any website can open a cross-origin WebSocket to ws://localhost:3357/ws (browser WebSocket is not subject to CORS) and (a) receive project snapshots, (b) submit params that trigger server-side CPU blowups affecting all connected clients.
Recommended fix
new WebSocketServer({ server, path: '/ws', maxPayload: 1<<20, verifyClient: originCheck })(or token subprotocol); validate params with a zod schema; anchor/validate glob patterns before regex compilation (and consider a bounded matcher instead of RegExp).