mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2026-05-06 14:03:40 +08:00
fix: enhance WebSocket origin validation for trusted node requests
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 = ""
|
||||
|
||||
Reference in New Issue
Block a user