Описание
nginx-ui's Unauthenticated MCP Endpoint Allows Remote Nginx Takeover
Summary
The nginx-ui MCP (Model Context Protocol) integration exposes two HTTP endpoints: /mcp and /mcp_message. While /mcp requires both IP whitelisting and authentication (AuthRequired() middleware), the /mcp_message endpoint only applies IP whitelisting - and the default IP whitelist is empty, which the middleware treats as "allow all". This means any network attacker can invoke all MCP tools without authentication, including restarting nginx, creating/modifying/deleting nginx configuration files, and triggering automatic config reloads - achieving complete nginx service takeover.
Details
Vulnerable Code
mcp/router.go:9-17 - Auth asymmetry between endpoints
The /mcp endpoint has middleware.AuthRequired(), but /mcp_message does not. Both endpoints route to the same mcp.ServeHTTP() handler, which processes all MCP tool invocations.
internal/middleware/ip_whitelist.go:11-26 - Empty whitelist allows all
When IPWhiteList is empty (the default - settings/auth.go initializes Auth{} with no whitelist), the middleware allows all requests through. This is a fail-open design.
Available MCP Tools (all invocable without auth)
From mcp/nginx/:
restart_nginx- restart the nginx processreload_nginx- reload nginx configurationnginx_status- read nginx status
From mcp/config/:
nginx_config_add- create new nginx config filesnginx_config_modify- modify existing config filesnginx_config_list- list all configurationsnginx_config_get- read config file contentsnginx_config_enable- enable/disable sitesnginx_config_rename- rename config filesnginx_config_mkdir- create directoriesnginx_config_history- view config historynginx_config_base_path- get nginx config directory path
Attack Scenario
- Attacker sends HTTP requests to
http://target:9000/mcp_message(default port) - No authentication is required - IP whitelist is empty by default
- Attacker invokes
nginx_config_modifywithrelative_path="nginx.conf"to rewrite the main nginx configuration (e.g., inject a reverse proxy that logsAuthorizationheaders) nginx_config_addauto-reloads nginx (config_add.go:74), or attacker callsreload_nginxdirectly- All traffic through nginx is now under attacker control - requests intercepted, redirected, or denied
PoC
1. The auth asymmetry is visible by comparing the two route registrations in mcp/router.go:
Both call the same mcp.ServeHTTP(c) handler, which dispatches all tool invocations.
2. The IP whitelist defaults to empty, allowing all IPs. From settings/auth.go:
And the middleware at internal/middleware/ip_whitelist.go:14 passes all requests when the list is empty:
3. Config writes auto-reload nginx. From mcp/config/config_add.go:
4. Exploit request. An attacker with network access to port 9000 can invoke any MCP tool via the SSE message endpoint. For example, to create a malicious nginx config that logs authorization headers:
No Authorization header is needed. The config is written and nginx reloads immediately.
Impact
- Complete nginx service takeover: An unauthenticated attacker can create, modify, and delete any nginx configuration file within the config directory, then trigger immediate reload/restart
- Traffic interception: Attacker can rewrite server blocks to proxy all traffic through an attacker-controlled endpoint, capturing credentials, session tokens, and sensitive data in transit
- Service disruption: Writing an invalid config and triggering reload takes nginx offline, affecting all proxied services
- Configuration exfiltration: All existing nginx configs are readable via
nginx_config_get, revealing backend topology, upstream servers, TLS certificate paths, and authentication headers - Credential harvesting: By injecting
access_logdirectives with customlog_formatpatterns, the attacker can captureAuthorizationheaders from administrators accessing nginx-ui, enabling escalation to the REST API
Remediation
Add middleware.AuthRequired() to the /mcp_message route:
Additionally, consider changing the IP whitelist default behavior to deny-all when unconfigured, rather than allow-all.
Ссылки
- https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-h6c2-x2m2-mwhf
- https://nvd.nist.gov/vuln/detail/CVE-2026-33032
- https://github.com/0xJacky/nginx-ui/blob/f89f8ff8223478988f7ed49bf1d3dbf2de44bf92/internal/middleware/ip_whitelist.go#L11-L26
- https://github.com/0xJacky/nginx-ui/blob/f89f8ff8223478988f7ed49bf1d3dbf2de44bf92/mcp/router.go#L9-L17
- https://websec.net/blog/cve-2026-33032-unauthenticated-nginx-ui-mcp-takeover-69e1200f9fceb1f3fbe9c47f
Пакеты
github.com/0xJacky/Nginx-UI
<= 1.99
Отсутствует
Связанные уязвимости
Nginx UI is a web user interface for the Nginx web server. In versions 2.3.5 and prior, the nginx-ui MCP (Model Context Protocol) integration exposes two HTTP endpoints: /mcp and /mcp_message. While /mcp requires both IP whitelisting and authentication (AuthRequired() middleware), the /mcp_message endpoint only applies IP whitelisting - and the default IP whitelist is empty, which the middleware treats as "allow all". This means any network attacker can invoke all MCP tools without authentication, including restarting nginx, creating/modifying/deleting nginx configuration files, and triggering automatic config reloads - achieving complete nginx service takeover. At time of publication, there are no publicly available patches.
Уязвимость пользовательского интерфейса Nginx UI сервера nginx, позволяющая нарушителю получить несанкционированный доступ к системе