Nginx-UI: Cross-Site WebSocket Hijacking (CSWSH) via missing origin validation on all WebSocket endpoints
Date: 2026-04
Affected: go/github.com/0xJacky/Nginx-UI
Attack vector: rce
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-34403
CWE: CWE-1385
CWE-352
CVSS: 8.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N)

## Summary All WebSocket endpoints in nginx-ui use a gorilla/websocket Upgrader with CheckOrigin unconditionally returning true, allowing Cross-Site WebSocket Hijacking (CSWSH). Combined with the fact that authentication tokens are stored in browser cookies (set via JavaScript without HttpOnly or explicit SameSite attributes), a malicious webpage can establish authenticated WebSocket connections to the nginx-ui instance when a logged-in administrator visits the attacker-controlled page. ## Details ### Vulnerable Code Pattern Every WebSocket endpoint in the codebase uses the same unsafe upgrader configuration: ```go // Found in: api/terminal/pty.go, api/analytic/analytic.go, api/event/websocket.go, // api/nginx_log/websocket.go, api/upstream/upstream.go, api/cluster/websocket.go, // api/nginx/websocket.go, api/certificate/revoke.go, api/sites/websocket.go, // api/llm/llm.go, api/llm/code_completion.go, api/system/upgrade.go var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // Accepts ALL origins }, } ``` ### Cookie-Based Authentication The Vue.js frontend stores JWT tokens as cookies without security attributes (app/src/pinia/moudule/user.ts): ```typescript watch(token, v => { cookies.set('token', v, { maxAge: 86400 }) // No HttpOnly, no SameSite }) ``` The backend middleware accepts tokens from cookies (internal/middleware/middleware.go): ```go func getToken(c *gin.Context) (token string) { // ... i


Mitigations:

Architectural layers (MAESTRO):