feat(security): enforce WSS for non-localhost connections
- Add SecurityError class for clear error handling - Add validateWebSocketSecurity function - Block ws:// connections to non-localhost hosts - Add unit tests for security validation logic Security: Prevents man-in-the-middle attacks on remote connections by requiring WSS protocol for all non-localhost WebSocket connections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,35 @@ import {
|
||||
import type { GatewayConfigSnapshot, GatewayModelChoice } from './gateway-config';
|
||||
import { installApiMethods } from './gateway-api';
|
||||
|
||||
// === Security ===
|
||||
|
||||
/**
|
||||
* Security error for invalid WebSocket connections.
|
||||
* Thrown when non-localhost URLs use ws:// instead of wss://.
|
||||
*/
|
||||
export class SecurityError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'SecurityError';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate WebSocket URL security.
|
||||
* Ensures non-localhost connections use WSS protocol.
|
||||
*
|
||||
* @param url - The WebSocket URL to validate
|
||||
* @throws SecurityError if non-localhost URL uses ws:// instead of wss://
|
||||
*/
|
||||
export function validateWebSocketSecurity(url: string): void {
|
||||
if (!url.startsWith('wss://') && !isLocalhost(url)) {
|
||||
throw new SecurityError(
|
||||
'Non-localhost connections must use WSS protocol for security. ' +
|
||||
`URL: ${url.replace(/:[^:@]+@/, ':****@')}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function createIdempotencyKey(): string {
|
||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
||||
return crypto.randomUUID();
|
||||
@@ -205,10 +234,8 @@ export class GatewayClient {
|
||||
return this.connectRest();
|
||||
}
|
||||
|
||||
// Security warning: non-localhost with insecure WebSocket
|
||||
if (!this.url.startsWith('wss://') && !isLocalhost(this.url)) {
|
||||
console.warn('[Gateway] Connecting to non-localhost with insecure WebSocket (ws://). Consider using WSS in production.');
|
||||
}
|
||||
// Security validation: enforce WSS for non-localhost connections
|
||||
validateWebSocketSecurity(this.url);
|
||||
|
||||
this.autoReconnect = true;
|
||||
this.setState('connecting');
|
||||
|
||||
Reference in New Issue
Block a user