Description
this.emit(data.type as string, data) emits whatever event name the server dictates, with zero validation. A malicious/compromised server can emit "connected", "disconnected", "error", or "reconnect" events, tricking the client into false state transitions, reconnection loops, or believing it's connected when it isn't.
Location
packages/xrpl/src/client/connection.ts#L357
Severity
Critical -- Remote event injection from a rogue server.
Adversarial Review Notes
The EventEmitter emit() only fires registered listeners. If no handlers are bound for a spoofed event name, the emit is a no-op. However, the Connection and Client classes DO register handlers for "connected", "disconnected", "error", etc. A rogue server sending {"type": "error", ...} could trigger error handlers. The lack of a whitelist is a genuine design issue.
Confidence: 90%
Unit Test Patch
No standalone unit test for this bug — requires WebSocket mocking. Suggested fix: add a whitelist of allowed event types before this.emit(data.type, ...), e.g. if (!ALLOWED_EVENTS.has(data.type)) return.
Description
this.emit(data.type as string, data)emits whatever event name the server dictates, with zero validation. A malicious/compromised server can emit"connected","disconnected","error", or"reconnect"events, tricking the client into false state transitions, reconnection loops, or believing it's connected when it isn't.Location
packages/xrpl/src/client/connection.ts#L357
Severity
Critical -- Remote event injection from a rogue server.
Adversarial Review Notes
The EventEmitter
emit()only fires registered listeners. If no handlers are bound for a spoofed event name, the emit is a no-op. However, the Connection and Client classes DO register handlers for"connected","disconnected","error", etc. A rogue server sending{"type": "error", ...}could trigger error handlers. The lack of a whitelist is a genuine design issue.Confidence: 90%
Unit Test Patch
No standalone unit test for this bug — requires WebSocket mocking. Suggested fix: add a whitelist of allowed event types before
this.emit(data.type, ...), e.g.if (!ALLOWED_EVENTS.has(data.type)) return.