mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-16 15:17:14 +00:00
fix(node): cap the status body the heartbeat probe decodes
probe decoded the node status response with json.NewDecoder(resp.Body) and no size limit. encoding/json buffers the whole value before decoding, so the allocation was dictated by the peer regardless of how few fields the envelope declares — and the heartbeat job probes up to 32 nodes concurrently on a 4s budget with no client-level timeout. The sibling RPC path already caps every node response at 64 MiB (readCappedBody in internal/web/runtime), so this was the one uncapped read of node-controlled data. A status envelope holds a handful of scalars, so the cap here is 1 MiB rather than the RPC figure. The peer is untrusted in the skip and pin TLS modes, and the same decode is reachable from the nodes test and probe endpoints.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -1203,6 +1204,10 @@ func (s *NodeService) withOutboundBridge(nodeID int, outboundTag string, fn func
|
||||
fn(proxyURL)
|
||||
}
|
||||
|
||||
// A status envelope holds a handful of scalars; the cap keeps a hostile or
|
||||
// broken node from dictating the master's allocation on every heartbeat.
|
||||
const maxProbeBodyBytes = 1 << 20 // 1 MiB
|
||||
|
||||
func (s *NodeService) probe(ctx context.Context, n *model.Node, proxyURL string) (HeartbeatPatch, error) {
|
||||
patch := HeartbeatPatch{LastHeartbeat: time.Now().Unix()}
|
||||
|
||||
@@ -1285,7 +1290,7 @@ func (s *NodeService) probe(ctx context.Context, n *model.Node, proxyURL string)
|
||||
} `json:"netIO"`
|
||||
} `json:"obj"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&envelope); err != nil {
|
||||
if err := json.NewDecoder(io.LimitReader(resp.Body, maxProbeBodyBytes)).Decode(&envelope); err != nil {
|
||||
patch.LastError = "decode response: " + err.Error()
|
||||
return patch, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user