Source: security-advisories@github.com
Signal K Server is a server application that runs on a central hub in a boat. Versions prior to 2.19.0 expose two features that can be chained together to steal JWT authentication tokens without any prior authentication. The attack combines WebSocket-based request enumeration with unauthenticated polling of access request status. The first is Unauthenticated WebSocket Request Enumeration: When a WebSocket client connects to the SignalK stream endpoint with the `serverevents=all` query parameter, the server sends all cached server events including `ACCESS_REQUEST` events that contain details about pending access requests. The `startServerEvents` function iterates over `app.lastServerEvents` and writes each cached event to any connected client without verifying authorization level. Since WebSocket connections are allowed for readonly users (which includes unauthenticated users when `allow_readonly` is true), attackers receive these events containing request IDs, client identifiers, descriptions, requested permissions, and IP addresses. The second is Unauthenticated Token Polling: The access request status endpoint at `/signalk/v1/access/requests/:id` returns the full state of an access request without requiring authentication. When an administrator approves a request, the response includes the issued JWT token in plaintext. The `queryRequest` function returns the complete request object including the token field, and the REST endpoint uses readonly authentication, allowing unauthenticated access. An attacker has two paths to exploit these vulnerabilities. Either the attacker creates their own access request (using the IP spoofing vulnerability to craft a convincing spoofed request), then polls their own request ID until an administrator approves it, receiving the JWT token; or the attacker passively monitors the WebSocket stream to discover request IDs from legitimate devices, then polls those IDs and steals the JWT tokens when administrators approve them, hijacking legitimate device credentials. Both paths require zero authentication and enable complete authentication bypass. Version 2.19.0 fixes the underlying issues.
Signal K Server versions prior to 2.19.0 are vulnerable to a critical authentication bypass, allowing attackers to steal JWT tokens without any prior authentication. This vulnerability combines unauthenticated WebSocket request enumeration and unauthenticated polling of access request status, enabling complete credential theft and potential control of the boat's systems.
Step 1: WebSocket Connection: An attacker connects to the Signal K stream endpoint (e.g., /signalk/v1/stream) with the serverevents=all query parameter via WebSocket.
Step 2: Event Enumeration: The server sends cached server events, including ACCESS_REQUEST events, to the attacker's WebSocket client. These events contain request IDs, client identifiers, descriptions, requested permissions, and IP addresses.
Step 3: Request ID Identification: The attacker analyzes the ACCESS_REQUEST events to identify request IDs, either from their own crafted requests (using IP spoofing) or from legitimate devices.
Step 4: Token Polling: The attacker uses the identified request IDs and polls the /signalk/v1/access/requests/:id endpoint to check the status of the access request.
Step 5: Token Acquisition (Attacker-Created Request): If the attacker created the request and an administrator approves it, the response from the polling endpoint includes the JWT token in plaintext.
Step 6: Token Acquisition (Legitimate Request Hijack): If the attacker monitors legitimate requests and an administrator approves one, the response from the polling endpoint includes the JWT token in plaintext, allowing the attacker to impersonate the legitimate device.
The vulnerability stems from two primary flaws: 1) The startServerEvents function in Signal K Server iterates through cached server events, including ACCESS_REQUEST events, and sends them to all connected WebSocket clients without proper authorization checks. This exposes sensitive information, including request IDs, client identifiers, and IP addresses. 2) The /signalk/v1/access/requests/:id endpoint allows unauthenticated access to the full state of access requests, including the issued JWT token when an administrator approves the request. The queryRequest function, used by the REST endpoint, retrieves the complete request object, including the token field, without verifying the user's authentication status. The root cause is a failure to implement proper access controls and authentication checks on sensitive data and API endpoints. The design flaw allows unauthenticated users to access information and functionality intended for authenticated administrators.
While no specific APTs are explicitly linked to this vulnerability, the ease of exploitation and the potential impact (control of a boat's systems) make it attractive to various threat actors. The vulnerability could be exploited by financially motivated actors, nation-state actors, or malicious insiders. CISA KEV status: Not Listed.
Monitor WebSocket traffic for connections to the Signal K stream endpoint with the serverevents=all parameter.
Analyze WebSocket traffic for the presence of ACCESS_REQUEST events.
Monitor HTTP traffic for requests to the /signalk/v1/access/requests/:id endpoint, especially from unexpected sources or without authentication headers.
Review server logs for suspicious activity, such as multiple requests to the access request endpoint from the same IP address or user agent.
Implement network intrusion detection systems (IDS) with rules to detect the described WebSocket and HTTP traffic patterns.
Upgrade to Signal K Server version 2.19.0 or later.
Implement proper authentication and authorization checks for all API endpoints, especially those handling sensitive data like JWT tokens and access request information.
Restrict access to the WebSocket stream endpoint and the access request endpoint to authenticated users only.
Review and harden the server's configuration, disabling unnecessary features and services.
Implement input validation to prevent IP spoofing and other potential attacks.
Regularly update the server software and all dependencies to patch any newly discovered vulnerabilities.