fix: enhance WebSocket origin validation for trusted node requests

This commit is contained in:
0xJacky
2026-04-03 11:31:41 +08:00
parent 02931d6c31
commit 7d9887bfe8
2 changed files with 22 additions and 2 deletions

View File

@@ -10,11 +10,17 @@ import (
)
// CheckWebSocketOrigin validates browser origins for WebSocket upgrade requests.
// Non-browser requests are only allowed for trusted node-to-node traffic.
// Trusted node-to-node traffic (via X-Node-Secret) is always allowed,
// regardless of the Origin header, because proxied requests carry the
// browser's original Origin which won't match the downstream node's host.
func CheckWebSocketOrigin(r *http.Request) bool {
if isTrustedNodeRequest(r) {
return true
}
origin := strings.TrimSpace(r.Header.Get("Origin"))
if origin == "" {
return isTrustedNodeRequest(r)
return false
}
if requestOrigin, ok := getRequestOrigin(r); ok && sameOrigin(origin, requestOrigin) {

View File

@@ -64,6 +64,20 @@ func TestCheckWebSocketOrigin(t *testing.T) {
assert.True(t, CheckWebSocketOrigin(req))
})
t.Run("allows node secret requests with cross-origin (proxy scenario)", func(t *testing.T) {
settings.HTTPSettings.WebSocketTrustedOrigins = nil
settings.NodeSettings.Secret = "node-secret"
// Simulates master node proxying WS to child node:
// Origin is the browser's master domain, but X-Node-Secret proves it's a trusted proxy.
req := httptest.NewRequest("GET", "http://127.0.0.1/ws", nil)
req.Host = "child-node:9000"
req.Header.Set("Origin", "https://master.example.com")
req.Header.Set("X-Node-Secret", "node-secret")
assert.True(t, CheckWebSocketOrigin(req))
})
t.Run("rejects cross site requests", func(t *testing.T) {
settings.HTTPSettings.WebSocketTrustedOrigins = nil
settings.NodeSettings.Secret = ""