# Nginx UI: MCP `nginx_config_add` Bypasses Directive Validation — Authenticated RCE

Nginx UI's MCP nginx_config_add tool skips directive blocklist validation, letting any authenticated user write perl/js_import configs and reload nginx for RCE.

- Payout: Research
- Severity: high
- Program: Nginx UI
- Found by: thekogo
- Disclosed: 2026-10-15
- CVE: CVE-2026-84318
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-9jww-cxg5-rj9m
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-9jww-cxg5-rj9m
- Tags: area:ai domain:ai domain:web impact:rce kind:research platform:ghsa sev:high tech:go tech:nginx technique:source-review vuln:auth-bypass vuln:misconfiguration vuln:rce

**Target:** MCP JSON-RPC tool endpoint (nginx_config_add) on Nginx UI
**Root cause:** mcp/config/config_add.go writes config content with os.WriteFile and reloads nginx without calling config.ValidateConfigFile, so the directive blocklist (perl, js_import, load_module, user root) enforced on the REST path is never applied.
**Steps:**
1. Control: `POST /api/configs` with perl content returns HTTP 500 code=40017 'file content contains restricted nginx directive'
2. `GET /mcp` with `Accept: text/event-stream` and Authorization token; extract sessionId from endpoint event
3. `POST /mcp_message?sessionId=<id>` with JSON-RPC `initialize` (protocolVersion 2024-11-05)
4. `POST /mcp_message?sessionId=<id>` with `tools/call` name `nginx_config_add`, arguments name `rce_backdoor.conf`, base_dir `conf.d`, overwrite true, content containing a `perl 'sub {...}'` handler under `location /rce`
5. File written to conf.d and nginx reloaded automatically (HTTP 200)
6. `GET http://<target>:8888/rce?cmd=id` returns `uid=101(nginx)`
**How found:** Compared the REST API config-add flow (which calls config.ValidateConfigFile) against the MCP tool implementation and noticed config_add.go omitted the validation call while config_modify.go included it.
**Exploitation:** Authenticated attacker (JWT or node-secret) opens an MCP SSE session, completes the JSON-RPC initialize handshake, then invokes nginx_config_add with a config containing a blocked perl directive. The tool writes the file and triggers nginx reload, activating a perl location handler that executes qx($cmd) from the cmd query parameter, yielding OS command execution as the nginx worker user.
**Escalation:** A `user root;` directive (also unblocked on this path) can raise the worker to root before the RCE handler fires.
**Insight:** When a product exposes the same privileged operation over multiple interfaces (REST, MCP, CLI), diff each handler against the validated one — sibling files in the same package often reveal the one missing the security check.

