MSS-SK-2026-0001
WebSocket auth bypass via unhandled Error type
Summary
When allow_readonly=false and no token is provided, authorizeWS() throws plain Error('Missing access token') (tokensecurity.ts:1441). The createPrimusAuthorize catch (ws.ts:907-916) only rejects InvalidTokenError/JsonWebTokenError/TokenExpiredError; plain Error falls through the else branch which calls authorized() with no argument — Primus treats that as success, silently admitting the unauthenticated WebSocket connection.
Impact
Any unauthenticated client on the boat network receives the full live SignalK stream — GPS, AIS, engine, autopilot status.
Evidence — code citations
Proof of concept
research/audits/signalk/exploits/0001-ws-auth-bypass.js/
-
0001-ws-auth-bypass.js— single-file — node research/audits/signalk/exploits/0001-ws-auth-bypass.js