Nginx UI: OTP secure-session step-up can be bypassed via MCP configuration tools
CVE-2026-84360 · GHSA-vc32-4gwf-77xp · published 15 Oct 2026
How serious is it
- Severity: high, CVSS score 8.1 out of 10.
- No exploit prediction (EPSS) score yet.
- Not on the CISA list of exploited vulnerabilities.
- No public exploit in Exploit-DB.
Is your app affected by CVE-2026-84360?
Paste this prompt into Claude Code, Cursor or any AI coding tool: it runs a free Shippable scan of your project and fixes what it finds. Built with Lovable, Bolt or v0? Scan your live app. Or upload your package file.
Who is affected
github.com/0xJacky/Nginx-UI(Go) < 1.9.10-0.20260703131214-23d1934099b0
How to check
- Run
go list -m github.com/0xJacky/Nginx-UIin your project to see the installed version, including copies pulled in by other packages. - Or paste your lockfile into the checker: it lists every package with a known vulnerability, this one included.
How to fix
Copies a prompt for Claude Code, Cursor or Codex: it checks your lockfiles for this and upgrades it.
- Upgrade
github.com/0xJacky/Nginx-UIto 1.9.10-0.20260703131214-23d1934099b0 or later, commit the lockfile and redeploy. - If a vulnerable version was live, check your logs and rotate the secrets that server could read.
The advisory
### Summary
An OTP-enabled authenticated user who cannot use the HTTP configuration mutation endpoints without a valid secure session can still mutate Nginx configuration through `/mcp` and `/mcp_message` using only ordinary authentication.
### Details
The HTTP configuration mutation surface is explicitly grouped behind `middleware.RequireSecureSession()`. By contrast, the MCP endpoints are exposed with only `middleware.AuthRequired()`. The MCP server exposes configuration mutation tools including `nginx_config_add` and `nginx_config_modify`, so OTP-enabled users gain an alternate path around the intended step-up requirement.
Relevant code paths:
- [api/config/router.go](/home/kali/Desktop/bounty/nginx-ui/api/config/router.go:14)
- [internal/middleware/secure_session.go](/home/kali/Desktop/bounty/nginx-ui/internal/middleware/secure_session.go:52)
- [mcp/router.go](/home/kali/Desktop/bounty/nginx-ui/mcp/router.go:9)
- [mcp/config/config_add.go](/home/kali/Desktop/bounty/nginx-ui/mcp/config/config_add.go:34)
- [mcp/config/config_modify.go](/home/kali/Desktop/bounty/nginx-ui/mcp/config/config_modify.go:55)
This is a security-control bypass rather than a missing feature. The product already established that OTP-enabled users should complete a secure session before high-impact configuration mutations are accepted on the HTTP path.
### PoC
I verified this locally in an isolated environment with a temporary end-to-end harness that exercised the real `/mcp` and `/mcp_message` routes.
What the executed test did:
1. Created a temporary config directory and configured Nginx control commands to harmless local values (`true`) to avoid touching the host.
2. Created a real OTP-enabled user in a temporary SQLite database.
3. Generated a real JWT for that OTP-enabled user.
4. Started a local test server exposing the real `/mcp` and `/mcp_message` routes.
5. Opened an authenticated SSE connection to `/mcp` with the JWT and no `X-Secure-Session-ID`.
6. Initialized the MCP session over `/mcp_message`.
7. Called the real `nginx_config_add` tool over `/mcp_message`.
8. Verified that the tool succeeded and created `mcp-bypass.conf` in the managed config directory without any secure-session step-up.
Observed result from the actual local verification:
- The MCP session initialized successfully without any `X-Secure-Session-ID`.
- The config file was written through the MCP tool path using only JWT authentication.
### Impact
OTP-enabled accounts lose the intended step-up protection for high-impact Nginx configuration changes when MCP is enabled. A user who should be blocked until re-authenticating can still create or modify configuration files and trigger reload behavior through MCP.
Check your whole app
Dependencies are only half of it. Free and read-only: before you push, run npx shippable-dev scan localhost:3000 in your project folder, no account needed. For your live app, you prove it's yours with a one-line tag first.
References
- github.com/0xJacky/nginx-ui/security/advisories/GHSA-vc32-4gwf-77xp
- nvd.nist.gov/vuln/detail/CVE-2026-84360
- github.com/0xJacky/nginx-ui/commit/23d1934099b05b2a01589b48129dc3d3159d91c2
- github.com/0xJacky/nginx-ui/releases/tag/v2.4.1
- github.com/advisories/GHSA-vc32-4gwf-77xp
Merged from GitHub Advisory Database. Last updated 23 Oct 2026. All vulnerabilities · RSS · JSON