Fix: Bind screen/terminal sub-conns only to the device's source IP
A screen or terminal sub-connection was keyed solely by a MasterID that any TCP peer may supply, so any internet host could claim an online device's MasterID and bind a sub-conn in its place, hijacking the live screen stream or a pending shell session. The ConnAuth signature cannot be verified on the server because its key lives in a vendored client library, so the trust anchor here is the source IP: sub-conns are always opened device-to-server from the same host as the login conn. BindScreenConn and BindTerminalConn now reject a sub-conn whose peer IP differs from the device's recorded main-connection PeerIP. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
53b7151fb7
commit
2de21b2b6b
2 files changed
+72
No files matched your search
@@ -299,6 +299,17 @@ func (h *Hub) BindScreenConn(deviceID string, ctx *connection.Context) bool {
|
||||
h.mu.Unlock()
|
||||
return false
|
||||
}
|
||||
// Bind only sub-connections that originate from the device's own main
|
||||
// connection source IP. Sub-conns are always opened device→server from
|
||||
// the same host as the login conn, so a source-IP mismatch means the
|
||||
// caller is not that device. This is the trust anchor for screen/terminal
|
||||
// sub-conns: the ConnAuth signature key lives in a vendored client
|
||||
// library and cannot be verified here, so without this check any internet
|
||||
// host could claim an online device's MasterID and hijack its stream.
|
||||
if d.PeerIP != "" && ctx.GetPeerIP() != d.PeerIP {
|
||||
h.mu.Unlock()
|
||||
return false
|
||||
}
|
||||
old := d.screenConn
|
||||
d.screenConn = ctx
|
||||
// The cached resolution and last IDR belong to the old encoder's
|
||||
@@ -693,6 +704,13 @@ func (h *Hub) BindTerminalConn(deviceID string, ctx *connection.Context, isPTY b
|
||||
h.mu.Unlock()
|
||||
return false
|
||||
}
|
||||
// Same trust anchor as BindScreenConn: a terminal sub-conn must come from
|
||||
// the device's own main-connection source IP, otherwise any internet host
|
||||
// could claim the pending session and hijack the shell.
|
||||
if d.PeerIP != "" && ctx.GetPeerIP() != d.PeerIP {
|
||||
h.mu.Unlock()
|
||||
return false
|
||||
}
|
||||
d.terminalConn = ctx
|
||||
d.terminalIsPTY = isPTY
|
||||
d.terminalPending = false
|
||||
|
||||
Reference in new issue
Block a user