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:
yuanyuanxianganddeepseek-v4-pro committed 2026-10-13 16:19:39 +02:00
1 parent 53b7151fb7
commit 2de21b2b6b
2 files changed
+72

No files matched your search

+18
View File
@@ -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