Skip to main content
VulnerabilityPublished

CVE-2026-42223: Nginx-UI Settings API Exposes Protected Secrets

Affects github.com/0xJacky/nginx-uiSource GCVE Database

0
Authoritative record:CVE-2026-42223· Medium 6.5

Not known to be exploited · CVSS 6.5 Medium : upgrade to 2.3.8 when convenient.

Data as of 27 Oct 2026, 00:07 UTC

CVSS 3.1 base score
6.5Medium
How severe the flaw is on the 0–10 CVSS scale.
Patch
Available – fixed in 2.3.8
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Exploitation evidence

  1. Disclosed: evidence found.

    CVE published 4 May 2026

  2. Detectable: no evidence on record.

    No public nuclei template indexed

  3. Weaponised: no evidence on record.

    No public exploit code indexed in Metasploit or Exploit-DB

  4. Exploited in the wild: no evidence on record.

    Not in CISA KEV and no source reports exploitation

  5. Observed by OffSeq Mirage: no evidence on record.

    No attack traffic recorded by OffSeq Mirage sensors

A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), the Metasploit, Exploit-DB and nuclei-templates index as of 26 Oct 2026.

What to do

Upgrade github.com/0xJacky/nginx-ui to 2.3.8.

Affected software

ProductAffectedFixed in
Gogithub.com/0xJacky/nginx-uiAffected
  • <2.3.8
Fixed in
  • 2.3.8

Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.

Description

### Summary The `GetSettings` API handler (`api/settings/settings.go:24-65`) serializes all settings structs to JSON and returns them to authenticated users. Many sensitive fields are tagged with `protected:"true"` - however, this tag is only enforced during writes (via `ProtectedFill` in `SaveSettings`) and is completely ignored during reads. This exposes 40+ protected fields including `JwtSecret` (enabling auth token forgery), `NodeSecret` (enabling cluster node impersonation), OIDC `ClientSecret` (enabling OAuth account takeover), and the IP whitelist configuration. ### Details #### Vulnerable Code **`api/settings/settings.go:49-64` - GetSettings serializes all fields** ```go c.JSON(http.StatusOK, gin.H{ "app": cSettings.AppSettings, "server": cSettings.ServerSettings, "database": settings.DatabaseSettings, "auth": settings.AuthSettings, "casdoor": settings.CasdoorSettings, "oidc": settings.OIDCSettings, "cert": settings.CertSettings, "http": settings.HTTPSettings, "logrotate": settings.LogrotateSettings, "nginx": settings.NginxSettings, "node": settings.NodeSettings, "openai": settings.OpenAISettings, "terminal": settings.TerminalSettings, "webauthn": settings.WebAuthnSettings, }) ``` Go's `json.Marshal` serializes all exported fields with `json:` tags. The `protected:"true"` struct tag is a custom tag - it has no effect on JSON serialization. #### Protection is Write-Only **`api/settings/settings.go:126-135` - ProtectedFill only used during saves** ```go cSettings.ProtectedFill(cSettings.AppSettings, &json.App) cSettings.ProtectedFill(cSettings.ServerSettings, &json.Server) cSettings.ProtectedFill(settings.AuthSettings, &json.Auth) // ... etc ``` `ProtectedFill` prevents overwriting protected fields during `SaveSettings`, but `GetSettings` has no corresponding filter. The protection is asymmetric - secrets can be read but not overwritten. #### Exposed Protected Fields **`settings/node.go`:** - `Secret` (protected) - used for cluster node authentication - `SkipInstallation` (protected), `Demo` (protected) **`settings/oidc.go` (all protected):** - `ClientId`, `ClientSecret`, `Endpoint`, `RedirectUri`, `Scopes`, `Identifier` **`settings/casdoor.go` (all protected):** - `Endpoint`, `ExternalUrl`, `ClientId`, `ClientSecret`, `CertificatePath`, `Organization`, `Application`, `RedirectUri` **`settings/auth.go`:** - `IPWhiteList` (protected) - exposes security configuration #### Attack Scenario 1. Low-privilege authenticated user calls `GET /api/settings` 2. Response includes `NodeSecret` - attacker can impersonate cluster nodes 3. Response includes OIDC `ClientSecret` - attacker can perform OAuth flows as the application 4. Response includes `IPWhiteList` - attacker learns network security configuration 5. If `JwtSecret` is in app settings (via cosy framework), attacker can forge authentication tokens for any user ### PoC **1. `GetSettings` serializes all fields** without filtering `protected:"true"` tags. From `api/settings/settings.go:49-64`: ```go c.JSON(http.StatusOK, gin.H{ "app": cSettings.AppSettings, "server": cSettings.ServerSettings, "database": settings.DatabaseSettings, "auth": settings.AuthSettings, "casdoor": settings.CasdoorSettings, "oidc": settings.OIDCSettings, "cert": settings.CertSettings, "http": settings.HTTPSettings, "logrotate": settings.LogrotateSettings, "nginx": settings.NginxSettings, "node": settings.NodeSettings, "openai": settings.OpenAISettings, "terminal": settings.TerminalSettings, "webauthn": settings.WebAuthnSettings, }) ``` Go's `json.Marshal` serializes all exported fields. The custom `protected:"true"` tag has no effect on serialization. **2. Protected secrets are defined** across `settings/*.go`. High-impact examples: ```go // settings/server_v1.go:19 JwtSecret string `json:"jwt_secret" protected:"true"` // settings/node.go:5 Secret string `json:"secret" protected:"true"` // settings/oidc.go ClientSecret string `json:"client_secret" protected:"true"` // settings/auth.go IPWhiteList []string `json:"ip_white_list" protected:"true"` ``` **3. `ProtectedFill` is write-only.** It appears 10 times in `SaveSettings` (lines 126-135) but 0 times in `GetSettings`: ```go // api/settings/settings.go:126-135 - Only used during writes cSettings.ProtectedFill(cSettings.AppSettings, &json.App) cSettings.ProtectedFill(cSettings.ServerSettings, &json.Server) cSettings.ProtectedFill(settings.AuthSettings, &json.Auth) // ... 7 more calls ``` **4. Exploit request.** Any authenticated user can retrieve all secrets: ```http GET /api/settings HTTP/1.1 Authorization: Bearer <any-valid-jwt> ``` Response includes (among 45 protected fields): ```json { "app": {"jwt_secret": "<the-actual-jwt-signing-key>", ...}, "node": {"secret": "<node-authentication-secret>", ...},

References

Community reviews

Loading reviews…