Business logic of attack: why the attacker Nginx UI
Nginx UI is an open-source web interface for managing Nginx with an active community on GitHub and a decent number of downloads from Docker Hub. Through the panel, administrators rule the configuration of virtual hosts, manage SSL certificates, reload the service. In a typical cinx-ui depot, it is facing production trunks, API gateways and internal services. This is not a side utility - this is a rumen through which all network traffic goes
According to Mandiant M-Trends 2025, exploits remain the dominant channel vector of initial access - 38% of all cases. CVE-2026-33032 - one of those rare cases where exploit requires nothing at all: neither privileges (PR:N), nor user actions (UI:N), nor complex preconditions (AC:L). CISA SSVC confirms: Automatable: yes, Technical Impact: total. A 50-stretch script and the operator fully controls the nginx configuration.
According to the IBM X-Force Thread Intelligence Index 2025, the average time between the publication of CVE and the elimination of 29 months in organizations. So the vulnerable nginx-ui constants will fall on the pentests long after the release of the patch. For the attacking value, the target is determined by the fact that control over nginx gives:
• Intercepting entire infrastructure traffic through upstream block manipulation
• Credential harvesting through custom logging directives
• Persistence through theft of JWT tokens signature key
• Intelligence internal topology - upstream hosts, backend ports, TLS certificates
Place in kill chain: pure initial access (T1190, Exploit Public-Facting Application) with immediate transition to post-exploitation. Classic foothold - download agent, getting reverse shell - no need. The attacker controls the infrastructure through the legitimate API panels. Why break the door if you were given the keys to the control room?
Anatomy CVE-2026-33032: nginx ui cve analysis
CVSS vector is read unambiguously: the attack is performed remotely over the network (AV:N), does not require difficult conditions (AC:L), does not require any privileges (PR:N), nor actions on the part of the victim (UI:N). Influence - the maximum for all three axes: confidentiality (C:H), integrity (I:H), accessibility (A:H). Scope does not change (S:U) - formally, the attack is limited by the nginx-ui component, although through the nginx configuration the consequences are spread to all proxy services.
Primary classification by NVD - CWE-306: lack of authentication for critical function. In terms of OWASP Top 10, the vulnerability falls on A05:2021 - Security Misconfiguration: fail-open behavior of the IP whitelist on an empty list is an educational example of an unsafe default. The operation of the unstoppled version falls under A06:2021 - Vulnerable and Outdated Components.
In the full chain of operation are additionally manifested CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) and CWE-73 (External Control of File Name or Path): via MCP-tool nginx_config_add the attacker controls both the name of the file and its contents. The NVD has only CWE-306 as a root cause, but when assessing a complete impact, these aspects should also be taken into account.
Missed AuthRequired() and fail-open whitelist
Nginx UI integrates MCP (Model Context Protocol) - an open standard for connecting AI assistants to external systems. Idea: The AI assistant configures nginx on behalf of the user. Sounds fashionable. In practice, it turned out a hole the size of a cargo container.
MCP-transport uses SSE (Server-Sent Events) with a two-endpoint architecture: GET /mcp opens SSE-stream and returns sessionID, POST /mcp_message accepts JSON-RPC MCP Tools calls. Both endpoints are routed for one processor mcp.ServeHTTP(c).
Vulnerable route registration code in mcp/router.go (according to the advisory GHSA-h6c2-x2-mwhf):
Code:
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) })
}
You see? Route /mcp Protected by two middleware: IPWhiteList() and AuthRequired(). Route /mcp_message - only IPWhiteList(). One missed call of the function. Exactly /mcp_message - the endpoint through which the client sends all the destructive calls of tools (conference, restart, reload). The privileged MCP handler is open through an unprotected path.
The second part of the problem is fail-open behavior of the whitlist. Midwar IPWhiteList() in the file internal/middleware/ip_whitelist.go check the length of the list: if len(settings.AuthSettings.IPWhiteList) == 0 or clientIP equal to 127.0.0.1/::1 - request is missed without verification (call c.Next()) Default configuration nginx-ui leaves ip_whitelist Empty. Empty Whitelist = Solve Everything. This is exactly what OWASP calls Security Misconfiguration: safety control, which in a default state does not protect anything.
Bottom line: any network attacker calls all 12 MCP tools without authentication. Among them are destructive (creation, change, deletion of nginx configuration files, restart, reboot, stop the service) and intelligence (config listing, reading files, nginx status).
Recon: fingerprinting vulnerable Nginx UI on web server
The standard port of nginx-ui is 9000/tcp. On the external pentest: Shodan-request for favicon hash (calculated through python3 favicon.py <url> from a live time station - check the specific value at the time of reconnaissance, it floats between versions) shows the instances with a characteristic favicon. According to the open data of Shodan, the instances are scattered across different regions and cloud providers.
On the internal pentest after the discovery of the open port - fast verification: curl -s http://target:9000/mcp_message -o /dev/null -w "%{http_code}". The answer code 200 or 400 instead of 401/403 means that the endpoint is available without authentication and nginx ui vulnerability is present. If 401 arrives, let’s move on.
For automated scanning in the official Repository of ProjectDiscovery, nuclei-templeet is available: nuclei -t http/cves/2026/CVE-2026-33032.yaml -u http://target:9000. There is also a template for the related CVE-2026-27944 - both checks in one pass.
Additional marker: availability of an endpoint GET /mcp, Responsible by SSE-stream (Content-Type text/event-stream) If both endpoints respond, confirmation that the MCP module is active.
When fingerprinting does not give results:
• Nginx-ui for reverse proxy with IP filtering at the level of external nginx/HAProxy - direct access to port 9000 is closed
• Non-standard port - you will need a complete scanning of TCP ports
• IP whitelist is full - IPWhiteList()will reject the request to the MCP-processor, and curlReturn 403
Nginx UI RCE: step-by-step operation of nginx ui vulnerability of remote code execution
Nginx UI is an open-source web interface for managing Nginx with an active community on GitHub and a decent number of downloads from Docker Hub. Through the panel, administrators rule the configuration of virtual hosts, manage SSL certificates, reload the service. In a typical cinx-ui depot, it is facing production trunks, API gateways and internal services. This is not a side utility - this is a rumen through which all network traffic goes
According to Mandiant M-Trends 2025, exploits remain the dominant channel vector of initial access - 38% of all cases. CVE-2026-33032 - one of those rare cases where exploit requires nothing at all: neither privileges (PR:N), nor user actions (UI:N), nor complex preconditions (AC:L). CISA SSVC confirms: Automatable: yes, Technical Impact: total. A 50-stretch script and the operator fully controls the nginx configuration.
According to the IBM X-Force Thread Intelligence Index 2025, the average time between the publication of CVE and the elimination of 29 months in organizations. So the vulnerable nginx-ui constants will fall on the pentests long after the release of the patch. For the attacking value, the target is determined by the fact that control over nginx gives:
• Intercepting entire infrastructure traffic through upstream block manipulation
• Credential harvesting through custom logging directives
• Persistence through theft of JWT tokens signature key
• Intelligence internal topology - upstream hosts, backend ports, TLS certificates
Place in kill chain: pure initial access (T1190, Exploit Public-Facting Application) with immediate transition to post-exploitation. Classic foothold - download agent, getting reverse shell - no need. The attacker controls the infrastructure through the legitimate API panels. Why break the door if you were given the keys to the control room?
Anatomy CVE-2026-33032: nginx ui cve analysis
CVSS vector is read unambiguously: the attack is performed remotely over the network (AV:N), does not require difficult conditions (AC:L), does not require any privileges (PR:N), nor actions on the part of the victim (UI:N). Influence - the maximum for all three axes: confidentiality (C:H), integrity (I:H), accessibility (A:H). Scope does not change (S:U) - formally, the attack is limited by the nginx-ui component, although through the nginx configuration the consequences are spread to all proxy services.
Primary classification by NVD - CWE-306: lack of authentication for critical function. In terms of OWASP Top 10, the vulnerability falls on A05:2021 - Security Misconfiguration: fail-open behavior of the IP whitelist on an empty list is an educational example of an unsafe default. The operation of the unstoppled version falls under A06:2021 - Vulnerable and Outdated Components.
In the full chain of operation are additionally manifested CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) and CWE-73 (External Control of File Name or Path): via MCP-tool nginx_config_add the attacker controls both the name of the file and its contents. The NVD has only CWE-306 as a root cause, but when assessing a complete impact, these aspects should also be taken into account.
Missed AuthRequired() and fail-open whitelist
Nginx UI integrates MCP (Model Context Protocol) - an open standard for connecting AI assistants to external systems. Idea: The AI assistant configures nginx on behalf of the user. Sounds fashionable. In practice, it turned out a hole the size of a cargo container.
MCP-transport uses SSE (Server-Sent Events) with a two-endpoint architecture: GET /mcp opens SSE-stream and returns sessionID, POST /mcp_message accepts JSON-RPC MCP Tools calls. Both endpoints are routed for one processor mcp.ServeHTTP(c).
Vulnerable route registration code in mcp/router.go (according to the advisory GHSA-h6c2-x2-mwhf):
Code:
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) })
}
You see? Route /mcp Protected by two middleware: IPWhiteList() and AuthRequired(). Route /mcp_message - only IPWhiteList(). One missed call of the function. Exactly /mcp_message - the endpoint through which the client sends all the destructive calls of tools (conference, restart, reload). The privileged MCP handler is open through an unprotected path.
The second part of the problem is fail-open behavior of the whitlist. Midwar IPWhiteList() in the file internal/middleware/ip_whitelist.go check the length of the list: if len(settings.AuthSettings.IPWhiteList) == 0 or clientIP equal to 127.0.0.1/::1 - request is missed without verification (call c.Next()) Default configuration nginx-ui leaves ip_whitelist Empty. Empty Whitelist = Solve Everything. This is exactly what OWASP calls Security Misconfiguration: safety control, which in a default state does not protect anything.
Bottom line: any network attacker calls all 12 MCP tools without authentication. Among them are destructive (creation, change, deletion of nginx configuration files, restart, reboot, stop the service) and intelligence (config listing, reading files, nginx status).
Recon: fingerprinting vulnerable Nginx UI on web server
The standard port of nginx-ui is 9000/tcp. On the external pentest: Shodan-request for favicon hash (calculated through python3 favicon.py <url> from a live time station - check the specific value at the time of reconnaissance, it floats between versions) shows the instances with a characteristic favicon. According to the open data of Shodan, the instances are scattered across different regions and cloud providers.
On the internal pentest after the discovery of the open port - fast verification: curl -s http://target:9000/mcp_message -o /dev/null -w "%{http_code}". The answer code 200 or 400 instead of 401/403 means that the endpoint is available without authentication and nginx ui vulnerability is present. If 401 arrives, let’s move on.
For automated scanning in the official Repository of ProjectDiscovery, nuclei-templeet is available: nuclei -t http/cves/2026/CVE-2026-33032.yaml -u http://target:9000. There is also a template for the related CVE-2026-27944 - both checks in one pass.
Additional marker: availability of an endpoint GET /mcp, Responsible by SSE-stream (Content-Type text/event-stream) If both endpoints respond, confirmation that the MCP module is active.
When fingerprinting does not give results:
• Nginx-ui for reverse proxy with IP filtering at the level of external nginx/HAProxy - direct access to port 9000 is closed
• Non-standard port - you will need a complete scanning of TCP ports
• IP whitelist is full - IPWhiteList()will reject the request to the MCP-processor, and curlReturn 403
Nginx UI RCE: step-by-step operation of nginx ui vulnerability of remote code execution