# 0xJacky/nginx-ui /api/nodes Leaks Cluster Node Tokens and Allows Cross-Node Impersonation as initUser

Nginx-UI's /api/nodes returns node token secrets to any authenticated user; replaying the token as X-Node-Secret authenticates as initUser on remote nodes.

- Payout: Research
- Severity: high
- Program: Nginx-UI
- Found by: PLpaPLpa
- Disclosed: 2026-10-09
- CVE: CVE-2026-107811
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-32gc-wf3m-78w9
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-32gc-wf3m-78w9
- Tags: area:web domain:web impact:internal-access impact:privesc kind:research platform:ghsa sev:high tech:go technique:source-review vuln:access-control vuln:auth-bypass vuln:info-disclosure

**Target:** Cluster node management API (/api/nodes, X-Node-Secret auth middleware)
**Root cause:** Cluster node list/detail handlers return model.Node including its JSON-serialized Token field to any authenticated user, and the same token is accepted as X-Node-Secret to elevate requests to initUser.
**Steps:**
1. Authenticate as a low-privileged user via `POST /api/login` with `name` and `password`; capture JWT.
2. Request `GET /api/nodes` or `GET /api/nodes/:id` with the low-privileged JWT.
3. Extract `url` and `token` from the JSON response.
4. Send `POST /api/system/restart` to the target node with header `X-Node-Secret: <leaked token>`.
5. Observe 200/success, confirming initUser-level access on the remote node.
**How found:** Source review of route mounting: cluster.InitRouter placed in shared AuthRequired group, model.Node Token field JSON-tagged, and middleware treating node secret match as initUser.
**Exploitation:** Low-priv user reads node token from /api/nodes, then replays it as X-Node-Secret against a remote node's management API; middleware matches settings.NodeSettings.Secret and sets user to initUser, granting administrative handlers like system restart, Nginx reload, and config sync.
**Escalation:** Cross-node lateral movement: leaked token grants initUser on every node sharing the secret, enabling cluster-wide management-plane compromise.
**Insight:** When a secret is both stored in a serialized model and accepted as an auth credential, check whether list/detail handlers return the raw model instead of a DTO; grep for JSON tags on credential fields and trace where the same value is compared in auth middleware.

