← Attack Database

MCPwn — nginx-ui Auth Bypass (CVE-2026-33032)

Protocol-level verified

MCPwn — nginx-ui Auth Bypass (CVE-2026-33032)

Summary

CVE-2026-33032, codenamed MCPwn by Pluto Security, is a CVSS 9.8 authentication-bypass bug in nginx-ui’s MCP integration. nginx-ui exposed two HTTP endpoints for MCP — /mcp and /mcp_message — but forgot to apply the auth middleware to /mcp_message. An unauthenticated attacker can reach the second endpoint and invoke every MCP tool the server exposes, including editing the nginx configuration and triggering reloads. It is the first major real-world MCP exploit and it has been actively exploited since before VulnCheck added it to its Known Exploited Vulnerabilities catalogue on 13 April 2026. Around 2,600–2,700 instances are publicly reachable on Shodan.

How it works

nginx-ui is a popular web interface for managing nginx (11k+ GitHub stars, 430k+ Docker pulls). In late 2025 it added MCP support so AI assistants could edit nginx configs. The implementation mounted two HTTP endpoints:

EndpointIP allow-listAuth middleware
/mcpYesAuthRequired()
/mcp_messageYesMissing

Two further failures turn a missing middleware call into unauthenticated RCE-equivalent control:

  1. Default IP allow-list is empty, which the middleware interprets as “allow all”. So the IP gate is open in any default install.
  2. MCP session IDs are not authenticated. An attacker POSTs to /mcp_message with a fresh session ID and immediately invokes tools.

The tools exposed include writing nginx config files, reloading nginx, and restarting the service — so a single unauthenticated HTTP request can plant an attacker-controlled config and reload it, achieving full control of the web server.

attacker ──POST /mcp_message (no auth)──► nginx-ui ──► MCP tools: write_config, reload_nginx

A separate earlier flaw — CVE-2026-27944 (CVSS 9.8, fixed in 2.3.3) — let attackers download an encrypted backup via /api/backup without authentication and recover the node_secret, which could be chained for deeper access on partially patched instances.

Real-world example

  • Vendor: nginx-ui (0xJacky/nginx-ui on GitHub).
  • Affected versions: 2.3.5 and earlier.
  • Fix: Version 2.3.4 added middleware.AuthRequired() to /mcp_message — a one-line change. Released mid-March 2026. (Note: sources report the fix in 2.3.4 even though 2.3.5 is the last “vulnerable” version; the ordering reflects back-ports.)
  • Exploitation: Listed among the 31 vulnerabilities Recorded Future tracked as actively exploited in March 2026. VulnCheck added it to its KEV catalogue on 13 April 2026.
  • Exposure: Shodan showed ~2,689 reachable nginx-ui instances at disclosure, concentrated in China, the US, Indonesia, Germany and Hong Kong.
  • Naming: “MCPwn” was coined by Pluto Security in their technical write-up.

Impact

  • Full takeover of the nginx web server exposed by nginx-ui. Attacker can rewrite configs, add reverse-proxy routes, terminate TLS, plant credential-harvesting pages, or drop arbitrary static content.
  • Because nginx typically fronts production web traffic, compromise cascades into every site that server serves.
  • On instances where the attacker chains CVE-2026-27944, they additionally recover long-lived secrets from backups.
  • Because the exploit only needs two HTTP requests with no auth, mass-scanning and indiscriminate exploitation are trivial.

Detection

  • Inventory MCP-enabled admin tools on your network. Any HTTP MCP endpoint that does not require auth should be treated as compromised until proven otherwise.
  • On nginx-ui hosts, check the version (/api/system) and upgrade to 2.3.4 or later.
  • In web-server logs, alert on requests to /mcp_message originating from external IPs.
  • Diff nginx.conf and included config files against a known-good baseline — MCPwn exploits leave traces as modified config files with unfamiliar directives.
  • Audit nginx for unexpected location blocks pointing at external upstreams.
  • Rotate any secrets that lived on the host: TLS private keys, upstream auth tokens, API keys embedded in config.

Prevention

A transport-layer policy engine sits between an MCP client and MCP server, so for a server like nginx-ui’s MCP endpoint, the engine can enforce authentication and scope at the wire level — regardless of whether the server itself remembers to apply its own middleware.

Example Intercept policy in front of any admin-plane MCP server:

version: "1"
description: "Admin MCP server — require review for config mutations"
default: "deny"

tools:
  # Read-only tools are allowed, but rate-limited.
  get_config:
    rules:
      - name: "read rate limit"
        rate_limit: 20/minute
        on_deny: "Config reads throttled"

  list_sites:
    rules: []

  # Any tool that writes config requires human approval.
  write_config:
    rules:
      - name: "approval for config writes"
        action: "require_approval"
        on_deny: "Config writes require human approval"

  reload_nginx:
    rules:
      - name: "approval for reload"
        action: "require_approval"
        on_deny: "Reloads require human approval"

  # Destructive actions are refused outright.
  delete_config:
    rules:
      - name: "no destructive actions"
        action: "deny"
        on_deny: "Destructive actions not permitted via MCP"

Structure follows the Intercept policy syntax (action: deny | require_approval, rate_limit). Not tested against a live MCPwn PoC.

Complementary host controls:

  • Upgrade nginx-ui to ≥ 2.3.4. This is the only real fix.
  • Bind nginx-ui management ports to localhost or a private admin VLAN, not 0.0.0.0.
  • Disable the MCP integration entirely if it is not in use.
  • Put a front-door reverse proxy in front of every admin UI that enforces auth independently.

Sources

  • MCP STDIO command injection
  • Token mis-redemption across MCP servers

Protect your agent in 30 seconds

Scans your MCP config and generates enforcement policies for every server.

npx -y @policylayer/intercept init
github.com/policylayer/intercept →
// GET IN TOUCH

Have a question or want to learn more? Send us a message.

Message sent.

We'll get back to you soon.