GHSA-m468-xcm6-fxg4 CVE-2026-33028 GO-2026-4906
nginx-ui has Race Condition that Leads to Persistent Data Corruption and Service Collapse
- Severity
- 0.0 / 10
- High · CVSS 4.0
- Exploit chance (EPSS)
- 0.55%
- Chance of exploitation in the next 30 days. Higher than 46.29% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
- Fix
1.30.1- Upgrade github.com/uozi-tech/cosy to this version or later
Description
Summary
The nginx-ui application is vulnerable to a Race Condition. Due to the complete absence of synchronization mechanisms (Mutex) and non-atomic file writes, concurrent requests lead to the severe corruption of the primary configuration file (app.ini). This vulnerability results in a persistent Denial of Service (DoS) and introduces a non-deterministic path for Remote Code Execution (RCE) through configuration cross-contamination.
Details
The vulnerability exists because the settings update pipeline does not implement any synchronization primitives. When multiple requests reach the handler simultaneously:
- Memory Corruption:
ProtectedFill()modifies shared global singleton pointers without thread-safety, leading to inconsistent states in memory. - File Corruption: The underlying library (
gopkg.in/ini.v1) performs direct overwrites. Concurrent write operations interleave at the OS level, resulting inapp.inifiles with empty leading lines, truncated fields, or partially overwritten configuration keys. - State Persistent Failure: Depending on which bytes are corrupted, the application either fails its "is-installed" check (redirecting to
/install) or encounters a fatal error during boot/runtime that prevents the process from responding to any further requests.
Environment:
- OS: Kali Linux 6.17.10-1kali1 (6.17.10+kali-amd64)
- Application Version: nginx-ui v2.3.3 (513) e5da6dd (go1.26.0)
- Deployment: Docker Container
PoC
-
Check original app.ini file valid state: <img width="524" height="367" alt="image" src="https://github.com/user-attachments/assets/d9688f76-7fe7-46ea-9eb9-c55bf40918a6" />
-
Log in to the
nginx-uidashboard. -
Navigate to Preferences and update settings. Capture a
POST /api/settingsrequest and send it to Burp Suite Intruder. -
Configure the attack with Null payloads (to test basic concurrency) or a Fuzzing list (to test data-driven corruption).
-
Set the Resource Pool to 20-50 concurrent requests. <img width="1188" height="776" alt="image" src="https://github.com/user-attachments/assets/403eef43-2bc6-4651-8802-15ddcb4f7631" />
-
Observation (In-flight corruption): Monitor the
app.inifile. You will observe the file being written with empty leading lines or incomplete key-value pairs.
-
<img width="1316" height="390" alt="image" src="https://github.com/user-attachments/assets/d99553f7-d253-4525-9b45-f59994e69180" />
-
<img width="1368" height="709" alt="image" src="https://github.com/user-attachments/assets/7522ba29-39f1-4c22-88f2-8e859cdb1984" />
- Observation (Recovery Failure): If the service redirects to
/install, attempting to complete the setup again often fails because the underlying configuration state is too corrupted to be reconciled by the installer logic. - Observation (Total Service Collapse): When the corruption in
app.inibecomes so severe, the Go runtime or the INI parser encounters a fatal error, causing the Nginx-UI service to stop responding entirely (Hard DoS).
<img width="1344" height="542" alt="image" src="https://github.com/user-attachments/assets/da4b99dc-ddce-4b79-b0bb-2d634bdd3bf7" />
-
Observation (Cross-Section Contamination): During testing, it was observed that sometimes INI sections become interleaved. For example, fields belonging to the
[nginx]section (likeConfigDirorReloadCmd) were erroneously written under the[webauthn]section.Example of corrupted output observed:
[webauthn]
RPDisplayName =
RPID =
RPOrigins =
gDirWhiteList =
ConfigDir = /etc/nginx
ConfigPath =
PIDPath = /run/nginx.pid
SbinPath =
TestConfigCmd =
ReloadCmd = nginx -s reload
RestartCmd = nginx -s stop
StubStatusPort = 51820
ContainerName =
Impact
This is a High security risk (CWE-362: Race Condition).
- Integrity: Permanent corruption of application settings and system-level configuration.
- Availability: High. The attack results in a persistent Denial of Service that cannot be recovered via the web UI.
- Remote Code Execution (RCE) Risk: Since the application allows updating certain fields (like Node Name) and uses others as shell commands (like ReloadCmd or RestartCmd), the observed "cross-contamination" of INI values means an attacker could potentially force a user-controlled string into a command execution field. If ReloadCmd is overwritten with a malicious payload provided in another field, the next nginx reload will execute that payload. While highly impactful, this specific exploit path is non-deterministic and depends on the precise interleaving of thread execution, making targeted exploitation difficult.
Recommended Mitigation
- Implement Mutex Locking: Wrap the
ProtectedFillandsettings.Save()calls in async.Mutexto serialize access to global settings. - Atomic File Writes: Implement a "write-then-rename" strategy. Write the new configuration to
app.ini.tmpand useos.Rename()to replace the original file atomically, ensuring the configuration file is always in a valid state.
A patched version of nginx-ui is available at https://github.com/0xJacky/nginx-ui/releases/tag/v2.3.4.
Affected versions
Go
| Package | Vulnerable | Fixed in |
|---|---|---|
| github.com/0xJacky/Nginx-UI | <= 1.99 |
No fix yet |
| github.com/0xJacky/Nginx-UI | all versions |
No fix yet |
| github.com/uozi-tech/cosy | < 1.30.1 |
1.30.1 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
github.com/uozi-tech/cosy Go → 1.30.1
- go
go get github.com/uozi-tech/cosy@v1.30.1 && go mod tidy
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:H/VA:H/SC:N/SI:N/SA:N
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- None
- Privileges required
- High
- User interaction
- None
- Confidentiality (vulnerable system)
- Low
- Integrity (vulnerable system)
- High
- Availability (vulnerable system)
- High
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
CVSS 3.1 7.5
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
- Attack vector
- Network
- Attack complexity
- High
- Privileges required
- Low
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Weakness
CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
The product contains a concurrent code sequence that requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence operating concurrently.
How to prevent it
- Architecture and Design: In languages that support it, use synchronization primitives. Only wrap these around critical code to minimize the impact on performance.
- Architecture and Design: Use thread-safe capabilities such as the data access abstraction in Spring.
- Architecture and Design: Minimize the usage of shared resources in order to remove as much complexity as possible from the control flow and to reduce the likelihood of unexpected conditions occurring. Additionally, this will minimize the amount of synchronization necessary and may even help to reduce the likelihood of a denial of service where an attacker may be able to repeatedly trigger a critical section (CWE-400).
- Implementation: When using multithreading and operating on shared variables, only use thread-safe functions.
- Implementation: Use atomic operations on shared variables. Be wary of innocent-looking constructs such as "x++". This may appear atomic at the code layer, but it is actually non-atomic at the instruction layer, since it involves a read, followed by a computation, followed by a write.
- Implementation: Use a mutex if available, but be sure to avoid related weaknesses such as CWE-412.
- Implementation: Avoid double-checked locking (CWE-609) and other implementation errors that arise when trying to avoid the overhead of synchronization.
- Implementation: Disable interrupts or signals over critical parts of the code, but also make sure that the code does not go into a large or infinite loop.
- Implementation: Use the volatile type modifier for critical variables to avoid unexpected compiler optimization or reordering. This does not necessarily solve the synchronization problem, but it can help.
- Architecture and Design, Operation: Run your code using the lowest privileges that are required to accomplish the necessary tasks [REF-76]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GO-2026-6773 Nginx UI: Casdoor SSO callback uses a constant `state` parameter (login CSRF) | High | Also affects github.com/0xJacky/Nginx-UI |
| GHSA-vc32-4gwf-77xp Nginx UI: OTP secure-session step-up can be bypassed via MCP configuration tools | High | Also affects github.com/0xJacky/Nginx-UI |
| GHSA-wq4w-vwvq-q3x9 Nginx UI: Standalone short tokens survive administrative revocation in cache and authenticate again after account re-enable | Medium | Also affects github.com/0xJacky/Nginx-UI |
| GHSA-jrq7-xrjx-pcfw Nginx UI: Auto backup name allows path traversal outside validated storage path | Medium | Also affects github.com/0xJacky/Nginx-UI |
| GHSA-5r62-gj48-897x Nginx UI: MCP configuration tools bypass restricted directive validation and allow secondary authenticated users to execute NJS in Nginx worker context | High | Also affects github.com/0xJacky/Nginx-UI |
| GHSA-9jww-cxg5-rj9m Nginx UI: MCP `nginx_config_add` Bypasses Directive Validation — Authenticated RCE | High | Also affects github.com/0xJacky/Nginx-UI |
| GHSA-76pm-mq2q-9gcr Nginx UI: MCP nginx_config_add skips config directive validation → authenticated nginx directive injection (RCE on the official image) | High | Also affects github.com/0xJacky/Nginx-UI |
| GHSA-cf23-7qxj-xmhr Nginx UI: nginx config directive denylist (ValidateConfigFile) is bypassable via same-line ";" separation → authenticated directive injection (RCE on the official image) | High | Also affects github.com/0xJacky/Nginx-UI |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor