Nginx UI CVE-2026-33032: Emergency Hardening Guide
CVE-2026-33032 is a CVSS 9.8 unauthenticated remote code execution vulnerability in Nginx UI, the popular web-based management interface built on Go and Vue. Any attacker with network access to port 9000 can invoke every MCP tool on your Nginx instance, rewrite configs, intercept traffic, and take the service completely offline, without providing a single credential. A public proof-of-concept has been available since March 28, 2026. There is no patch.
This guide walks you through what the vulnerability actually does at the code level, the exact steps to block exploitation right now, detection rules you can deploy today, and a verification procedure so you know your mitigation held. If Nginx UI is running in your environment and it is reachable from anything other than localhost, stop reading the intro and jump to the hardening steps.
What CVE-2026-33032 Actually Does
Nginx UI introduced Model Context Protocol (MCP) support, which exposes an HTTP-based tool-calling interface so AI assistants and automation clients can manage Nginx configuration programmatically. The integration registers two routes in mcp/router.go: /mcp and /mcp_message.
The /mcp route correctly applies two middleware layers: IP whitelisting and AuthRequired(). The /mcp_message route applies only the IP whitelist. Both routes feed the same mcp.ServeHTTP(c) handler, which dispatches all tool invocations. The result is that bypassing authentication on /mcp_message gives an attacker full tool access, identical to what an authenticated session through /mcp would provide.
The second failure compounds the first. The IP whitelist middleware in internal/middleware/ip_whitelist.go checks whether the whitelist is empty and, if it is, allows all requests through. Since the default configuration in settings/auth.go initializes the Auth struct with no IP whitelist populated, every fresh installation of Nginx UI is fail-open by design. An attacker does not need to spoof an IP or bypass a firewall rule. They need only reach TCP port 9000.
The full CVSS 3.1 vector is AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. Network accessible, low complexity, no privileges required, no user interaction required. Confidentiality, integrity, and availability all rated high. The GitHub Security Advisory (GHSA-h6c2-x2m2-mwhf) was published on March 28, 2026 and NVD received the record on March 30, 2026. The CWE classification is CWE-306: Missing Authentication for Critical Function.
The Attack Surface: 13 MCP Tools Without Auth
Once an attacker posts to /mcp_message, they have access to the complete MCP tool set. The advisory documents 13 tools across two namespaces.
From mcp/nginx/: restart the nginx process via restart_nginx, reload configuration via reload_nginx, and read runtime status via nginx_status.
From mcp/config/: create new config files (nginx_config_add), modify existing files (nginx_config_modify), list all configurations (nginx_config_list), read any config file (nginx_config_get), enable or disable sites (nginx_config_enable), rename files (nginx_config_rename), create directories (nginx_config_mkdir), view change history (nginx_config_history), and retrieve the config base path (nginx_config_base_path).
The nginx_config_add tool automatically triggers a reload after writing a file, at line 74 of config_add.go. An attacker writing a malicious config does not need to call reload_nginx separately. The config takes effect immediately. A single unauthenticated POST request can rewrite your main nginx.conf and have the change live before your monitoring system fires an alert.
The attack chain documented in the PoC: send a POST to http://target:9000/mcp_message with a JSON-RPC 2.0 payload calling nginx_config_add. The payload creates a server block that proxies all traffic through an attacker-controlled endpoint and logs Authorization headers to a file on disk. No auth header required. Nginx reloads. All traffic is now intercepted.
Emergency Hardening Steps
As of March 31, 2026, the Nginx UI maintainer has published no patched release. The advisory lists Patched versions: None, covering all affected versions through 2.3.5. Your options are network isolation, firewall rules, and manual code patching if you run a self-hosted instance from source.
Step 1: Block external access to port 9000 immediately.
If your system runs iptables, run these two commands to restrict port 9000 to your management IP and drop everything else:
iptables -I INPUT -p tcp --dport 9000 -s YOUR_MGMT_IP -j ACCEPT iptables -I INPUT -p tcp --dport 9000 -j DROP
On nftables (common on modern Ubuntu and Debian):
nft add rule inet filter input tcp dport 9000 ip saddr != YOUR_MGMT_IP drop
If Nginx UI sits behind a cloud security group, remove any 0.0.0.0/0 inbound rule for TCP 9000 and replace it with a rule scoped to your VPN CIDR or bastion host IP. Do this before anything else.
Step 2: Bind Nginx UI to localhost only.
Locate your Nginx UI configuration file, typically at /etc/nginx-ui/app.ini, and set the server host to 127.0.0.1:
[server] Host = 127.0.0.1 Port = 9000
Restart the service after the change:
systemctl restart nginx-ui
With this binding in place, the /mcp_message endpoint is only reachable from the local machine. Remote exploitation is impossible without prior host compromise.
Step 3: Populate the IP whitelist in Nginx UI settings.
Even though the IP whitelist middleware has a fail-open default, populating the list activates enforcement. Log in to your Nginx UI admin panel, go to System Settings, and add your management IP or CIDR to the IP Whitelist field. Save and restart. This activates the whitelist check and removes the default allow-all bypass.
Step 4 (source installs only): Apply the auth middleware patch manually.
If you maintain your own build, the fix is a single line in mcp/router.go. Change the /mcp_message route from this:
r.Any("/mcp_message", middleware.IPWhiteList(),
func(c *gin.Context) {
mcp.ServeHTTP(c)
})
To this:
r.Any("/mcp_message", middleware.IPWhiteList(), middleware.AuthRequired(),
func(c *gin.Context) {
mcp.ServeHTTP(c)
})
The AuthRequired() middleware is already implemented and working on the /mcp route. This patch closes the auth asymmetry at the source. Rebuild and redeploy.
Step 5: Audit your Nginx configuration for injected blocks.
If Nginx UI was internet-accessible before you applied these controls, check for unauthorized configuration files:
find /etc/nginx -name "*.conf" -newer /etc/nginx/nginx.conf -ls find /etc/nginx/conf.d -name "*.conf" -ls
Look for proxy_pass directives pointing to external IP addresses, access_log directives writing to unusual file paths, and server blocks you do not recognize. Any config file with a recent modification timestamp that you did not create warrants full forensic investigation.
Detection Rules and Log Queries
These rules are ready to deploy and cover the three layers where exploitation leaves traces: web server logs, SIEM events, and file system writes.
Nginx access log query for exploitation attempts:
grep "POST /mcp_message" /var/log/nginx-ui/access.log grep "POST /mcp_message" /var/log/nginx/access.log
Any POST to /mcp_message from an IP that is not your legitimate management station is a potential exploitation attempt. An HTTP 200 response code confirms the tool invocation succeeded and the action was applied.
Sigma rule for SIEM ingestion:
title: Nginx UI CVE-2026-33032 MCP Endpoint Abuse
id: cve-2026-33032-nginx-ui-mcp
status: stable
description: Detects unauthenticated POST requests to /mcp_message on Nginx UI
logsource:
category: webserver
detection:
selection:
cs-method: POST
cs-uri-stem|contains: '/mcp_message'
filter_auth:
cs-headers|contains: 'Authorization'
condition: selection and not filter_auth
falsepositives:
- Legitimate MCP clients that incorrectly omit the Authorization header
level: critical
tags:
- attack.initial_access
- attack.T1190
- cve.2026.33032
YARA rule for detecting exploit payloads in memory or log files:
rule CVE_2026_33032_NginxUI_MCP_Exploit {
meta:
description = "Detects CVE-2026-33032 exploit payloads targeting Nginx UI /mcp_message"
author = "ShieldOperations"
date = "2026-03-31"
cve = "CVE-2026-33032"
strings:
$endpoint = "/mcp_message" ascii
$method1 = "nginx_config_modify" ascii
$method2 = "nginx_config_add" ascii
$method3 = "restart_nginx" ascii
$jsonrpc = "\"jsonrpc\"" ascii
$tools_call = "\"tools/call\"" ascii
condition:
$endpoint and $jsonrpc and $tools_call and any of ($method1, $method2, $method3)
}
auditd rules to catch unauthorized file writes in the Nginx config directory:
-w /etc/nginx/ -p wa -k nginx_config_tamper -w /etc/nginx/conf.d/ -p wa -k nginx_config_tamper
Add these to /etc/audit/rules.d/nginx.rules and reload with auditctl -R /etc/audit/rules.d/nginx.rules. Any write to the Nginx config directory generates an audit event tagged nginx_config_tamper, which your SIEM can alert on in real time.
Patch Verification Procedure
After applying hardening controls, verify each one is working. Do not assume the controls took effect without testing.
Verify port 9000 is not externally accessible. Run this from an external host, not the server itself:
nc -zv TARGET_IP 9000 # Expected: Connection refused or connection timed out
Verify localhost binding:
ss -tlnp | grep 9000 # Expected: 127.0.0.1:9000 (not 0.0.0.0:9000)
Verify the /mcp_message endpoint requires authentication (for patched source builds only):
curl -s -o /dev/null -w "%{http_code}" \
-X POST http://127.0.0.1:9000/mcp_message \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"nginx_status","arguments":{}},"id":1}'
# Expected: 401
# If you receive 200: the auth patch did not apply correctly
Verify the service is running after config changes:
systemctl status nginx-ui journalctl -u nginx-ui -n 50 --no-pager
Scope of Exposure
Nginx UI has 10,900 GitHub stars and 793 forks as of the advisory publication date, March 28, 2026. The project is widely deployed by developers and small infrastructure teams who prefer a GUI to direct Nginx config editing. The vulnerability affects all versions through 2.3.5.
Exposure is highest in three scenarios: deployments where Nginx UI is directly internet-facing with no firewall restricting port 9000; cloud VM deployments with permissive security group rules that open all ports by default; and Docker deployments where the container publishes port 9000 with -p 9000:9000 without additional network segmentation.
Internal network exposure is real too. An attacker with internal network access, via a phishing pivot, compromised workstation, or supply chain position, can reach the unprotected endpoint across a flat corporate network. The attack maps to MITRE ATT&CK T1190 (Exploit Public-Facing Application) for internet-accessible instances and T1552 (Unsecured Credentials) for the credential harvesting capability via injected access_log directives.
If you are working through a broader incident response plan following suspicious activity on a system running Nginx UI, the incident response planning guide for UK organisations covers the containment and evidence collection steps to run in parallel with these hardening actions.
Two Different Nginx UI CVEs: How They Differ
Security coverage in early 2026 has conflated two separate Nginx UI vulnerabilities, which creates confusion about scope and whether you are protected.
CVE-2026-27944 (reported March 9-10, 2026) involves an unauthenticated /api/backup endpoint that exposes AES-256 encryption keys in the X-Backup-Security response header, allowing any caller to download and immediately decrypt a full server backup. That flaw was addressed in Nginx UI version 2.3.3.
CVE-2026-33032 is newer, published March 30, 2026, and affects all versions including 2.3.5. If you patched for CVE-2026-27944 and are running 2.3.3 or later, you are still fully exposed to CVE-2026-33032. These are not duplicates. They hit different endpoints and require separate remediation.
The pattern of two critical authentication bypass flaws in the same project within three weeks suggests the MCP integration shipped without adequate security review. Anyone running Nginx UI should treat the entire management interface as high-risk until a comprehensive security audit is published by the maintainer.
For a comparable situation where MCP-adjacent attack surfaces created immediate compromise risk in AI tooling, the Langflow CVE-2026-33017 hardening guide documents a similar methodology. The network isolation and auth verification steps carry over directly.
When a Patch Lands
Watch the releases page at github.com/0xJacky/nginx-ui and the security advisories tab. When a patched version appears, test in a non-production environment first, verify the /mcp_message endpoint returns 401 for unauthenticated requests after upgrade, then roll to production.
Before upgrading any internet-facing instance, rotate all credentials associated with that server: Nginx UI admin passwords, SSL private keys stored in the backed-up config directory, and any API tokens that appeared in Nginx access logs during the exposure window. If you cannot confirm the exact exposure window, assume all credentials that touched that server are compromised and rotate accordingly.
Keep port 9000 restricted to management IPs even after patching. A patched auth bug does not justify opening the management interface to the internet. This aligns with the core principle from the zero trust architecture guide: management planes require explicit, verified access regardless of patch status.
Frequently Asked Questions
Is CVE-2026-33032 the same as the Nginx web server CVE?
No. CVE-2026-33032 affects Nginx UI, a third-party web-based management interface for Nginx, not the Nginx web server itself. The core Nginx binary at nginx.org is not affected. If you run Nginx without the Nginx UI management panel installed, this vulnerability does not apply to your installation.
What Nginx UI versions are affected by CVE-2026-33032?
All versions of Nginx UI through 2.3.5 are affected. The vulnerability was introduced with the MCP integration feature. No patched version exists as of March 31, 2026. Monitor the official GitHub repository at github.com/0xJacky/nginx-ui for a patched release and subscribe to the security advisories section specifically.
Can I detect whether my Nginx UI was already exploited?
Check your Nginx UI access logs for POST requests to /mcp_message that returned HTTP 200. Review Nginx config files in /etc/nginx/conf.d/ for unexpected proxy_pass directives or access_log entries pointing to unusual paths. Run find /etc/nginx -name "*.conf" -newer /etc/nginx/nginx.conf -ls to surface recently modified files. Any file you do not recognize warrants a full forensic review.
Does disabling MCP in Nginx UI settings fully mitigate the vulnerability?
Possibly, but do not rely on it as your only control. Whether disabling MCP prevents route registration depends on application startup logic, which has not been independently verified in the current codebase. Firewall blocking port 9000 from external access operates at a layer independent of the application and is the more reliable control. Use both together.
Is CVE-2026-33032 being actively exploited in the wild?
A public PoC was included in GitHub Security Advisory GHSA-h6c2-x2m2-mwhf, published March 28, 2026. Zero authentication, low complexity, and a published PoC mean automated scanning tools will incorporate this rapidly. Treat it as actively exploited until you have confirmed evidence otherwise.
What should I do if I cannot immediately restrict access to Nginx UI?
Disable the Nginx UI service entirely: systemctl stop nginx-ui && systemctl disable nginx-ui. Your Nginx web server will continue operating normally since Nginx UI is a management tool only. Stopping it has no effect on live traffic passing through Nginx itself. Re-enable only after network-level controls are in place.