Signal K Server: Buffered logs exposed to unauthenticated WebSocket clientsGHSA-7m8x-x364-m26j
MEDIUMFix: SignalK/signalk-server@1bee851GHSA-7m8x-x364-m26j is a medium-severity (CVSS 5.3) vulnerability in signalk-server. A fix is available for signalk-server — see the affected versions and patch details below.
Real-World Exposure
How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.
signalk-servernpmDescription
Summary
An unauthenticated WebSocket client can subscribe to the log path and receive buffered server logs.
WebSocket connections are intentionally permitted before authentication because login occurs over the WebSocket connection. However, the log subscription path does not enforce an authorization check.
processSubscribe handles subscriptions to the log path separately, without applying access control:
if (
Array.isArray(msg.subscribe) &&
msg.subscribe.length > 0 &&
msg.subscribe[0].path === 'log'
) {
if (!spark.logUnsubscribe) {
spark.logUnsubscribe = startServerLog(app, spark)
}
} else {
// normal subscriptions go through subscriptionmanager, which applies
// securityStrategy.filterReadDelta
}
startServerLog then replays the whole buffer to that socket:
app.logging.getLog().forEach((log) => {
spark.write({ type: 'LOG', data: log })
})
The asymmetry is inside this one file. Writes are gated by securityStrategy.shouldAllowWrite (ws.ts:961), normal delta subscriptions are filtered by securityStrategy.filterReadDelta (ws.ts:1159, the else branch of this same function), and the log branch consults neither.
An unauthenticated socket, which is legitimately open for login, can subscribe to log and receive buffered server logs.
Fix: Requires an administrator principal, before startServerLog, in the same way the other branch defers to securityStrategy. The fix was released with version 2.31.0-beta.1.
The investigated code path was reviewed at commit 26ab199. No server was run and no WebSocket frames were captured. AI assistance was used during the investigation.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | signalk-server | all versions | 2.31.0-beta.1npm install signalk-server@2.31.0-beta.1 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for signalk-server, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update signalk-server to 2.31.0-beta.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-7m8x-x364-m26j is resolved across your whole dependency graph.
Workarounds
Put an independent control in front of the weakness: restrict the affected endpoint or interface to trusted networks, require an additional authentication factor or proxy-level check, and invalidate existing sessions and credentials in case the flaw has already been used.
Frequently Asked Questions
Is GHSA-7m8x-x364-m26j in your dependencies?
Find it across npm, including transitive dependencies.