GitHub Security Advisory: GHSA-7jrr-xw9c-mj39
Package: github.com/0xJacky/Nginx-UI (GO)
Severity: MODERATE (CVSS 6.5)
CWE: CWE-200: Exposure of Sensitive Information to an Unauthorized Actor, CWE-863: Incorrect Authorization
Vulnerable versions: <= 1.9.9
Patched in: unpatched

Summary: Nginx-UI: Authenticated settings disclosure exposes node.secret and enables trusted-node authentication abuse, backup exfiltration, and restore-based nginx-ui state rollback

Details:
## Summary
An authenticated user can call `GET /api/settings` and retrieve sensitive configuration values, including `node.secret`. The same `node.secret` is accepted by `AuthRequired()` through the `X-Node-Secret` header (or `node_secret` query parameter), causing the request to be treated as authenticated via the trusted-node path and associated with the init user.
In my local reproduction on `v2.3.6`, `GET /api/settings` also returned `app.jwt_secret`. After extracting `node.secret`, I was able to access `GET /api/backup` using only `X-Node-Secret`, download a full backup archive, and obtain the `X-Backup-Security` response header containing the backup decryption material (`AESKey:AESIv`).
I also confirmed that the disclosed `node.secret` is sufficient to reach the restore workflow on an installed instance. Using only `X-Node-Secret`, a valid backup archive, and its matching `X-Backup-Security` token, I successfully invoked `POST /api/restore`. In a follow-up rollback test, I changed `node.name` to `rollback-poc-B`, then restored a previously captured backup and observed the value revert to its original state. This extends the issue beyond secret disclosure and backup exfiltration into confirmed integrity impact through restore-based rollback of nginx-ui state/configuration.
This breaks the trust boundary between ordinary user-authenticated API access and the internal node-authentication mechanism, and results in sensitive configuration disclosure, alternate-authentication abuse, backup exfiltration with decryption material, and confirmed restore-based rollback of nginx-ui state.

## Details
### Vulnerable code / related files and functions

**1) Route exposure and insufficient protection on the read path**

File: `api/settings/router.go`

Relevant function: `InitRouter`

The settings router exposes the following endpoints:
```http
GET /api/settings/server/name → GetServerName
GET /api/settings → GetSettings
POST /api/settings → RequireSecureSession(), SaveSettings
```

The key issue is that the read path (GET /api/settings) is only protected by the generic authentication middleware, while the write path (POST /api/settings) has an additional RequireSecureSession() check. This makes the read path a much easier place to leak sensitive configuration data than the write path.
```go
r.GET("settings/server/name", GetServerName)
r.GET("settings", GetSettings)
r.POST("settings", middleware.RequireSecureSession(), SaveSettings)
```

**2) Sensitive data is disclosed by GetSettings**

File: `api/settings/settings.go`

Relevant functions: GetSettings, SaveSettings

`GetSettings` returns multiple configuration objects directly in the JSON response, including app, server, database, auth, casdoor, oidc, cert, http, logrotate, nginx, node, openai, terminal, and webauthn. In other words, the handler does not use a redacted DTO for user-facing output; it serializes the live settings objects directly.

```go
c.JSON(http.StatusOK, gin.H{
  "app":       cSettings