Skip to content

← Public intelligence

Go package

github.com/0xJacky/Nginx-UI

Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.

Open advisories

31 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.

  1. High, CVSS 7.1GoAmendedPublished

    Nginx UI: Casdoor SSO callback uses a constant state parameter (login CSRF)

    CVE-2026-84312 · GHSA-44xr-mrhh-qm78

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    In the Casdoor SSO flow, the OAuth `state` parameter is hard-coded to `settings.CasdoorSettings.Application` — a value identical for every user and every login. The callback handler accepts whatever `state` the client sends without comparing it to anything stored in the user agent, enabling a login-CSRF: an attacker can force the victim's browser to authenticate as the *attacker*. Details `api/user/casdoor.go:92-117` (`GetCasdoorUri`): ```go func GetCasdoorUri(c *gin.Context) { clientId := settings.CasdoorSettings.ClientId redirectUri := settings.CasdoorSettings.RedirectUri state := settings.CasdoorSettings.Application // ← constant ... c.JSON(http.StatusOK, gin.H{ "uri": fmt.Sprintf( "%s/login/oauth/authorize?client_id=%s&response_type=code&redirect_uri=%s&state=%s&scope=read", endpoint, clientId, encodedRedirectUri, state), }) } ``` `api/user/casdoor.go:24-90` (`CasdoorCallback`): ```go type CasdoorLoginUser struct { Code string `json:"code"…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)osv.dev (3)Source checked Evidence →
  2. High, CVSS 8.8GoAmendedPublished

    Nginx UI: TOTP / passkey enrolment requires no re-authentication, enabling persistent account takeover

    CVE-2026-84313 · GHSA-gfrc-g87h-7h5w

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    Endpoints that bind a TOTP secret (`POST /api/otp_enroll`) or register a WebAuthn passkey (`POST /api/finish_passkey_register`) for the *current* user require only a valid JWT. There is no current-password re-prompt and the routes are explicitly registered outside the `RequireSecureSession()` group. With only a stolen JWT, an attacker can attach their own second factor to the victim's account, surviving any subsequent password rotation and locking the legitimate user out. Details `api/user/router.go:34-39` — note the routes registered *before* the secure-session group: ```go r.GET("/otp_secret", GenerateTOTP) r.POST("/otp_enroll", EnrollTOTP) // ← outside RequireSecureSession r.GET("/begin_passkey_register", BeginPasskeyRegistration) r.POST("/finish_passkey_register", FinishPasskeyRegistration) // ← outside RequireSecureSession o := r.Group("", middleware.RequireSecureSession()) { o.GET("/otp_reset", ResetOTP) // reset *is* protected — inconsistent ... } ```…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)osv.dev (3)Source checked Evidence →
  3. High, CVSS 8.1GoAmendedPublished

    Nginx UI: OTP secure-session step-up can be bypassed via MCP configuration tools

    CVE-2026-84360 · GHSA-vc32-4gwf-77xp

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    An OTP-enabled authenticated user who cannot use the HTTP configuration mutation endpoints without a valid secure session can still mutate Nginx configuration through /mcp and /mcpmessage using only ordinary authentication. Details The HTTP configuration mutation surface is explicitly grouped behind middleware.RequireSecureSession(). By contrast, the MCP endpoints are exposed with only middleware.AuthRequired(). The MCP server exposes configuration mutation tools including nginxconfigadd and nginxconfigmodify, so OTP-enabled users gain an alternate path around the intended step-up requirement. Relevant code paths: - api/config/router.go - internal/middleware/securesession.go - mcp/router.go - mcp/config/configadd.go - mcp/config/configmodify.go This is a security-control bypass rather than a missing feature. The product already established that OTP-enabled users should complete a secure session before high-impact configuration mutations are accepted on the HTTP path. PoC I…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  4. Medium, CVSS 5.4GoAmendedPublished

    Nginx UI: Standalone short tokens survive administrative revocation in cache and authenticate again after account re-enable

    CVE-2026-84321 · GHSA-wq4w-vwvq-q3x9

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    Standalone short tokens issued for WebSocket and explicit-token authentication can survive administrative revocation in cache. If the same account is later re-enabled before the cache entry expires, the deleted short token becomes valid again. Details GenerateShortToken() creates an AuthToken row that contains only ShortToken and no long Token. DeleteUserTokens() removes database rows, but when clearing caches it only invalidates entries where authToken.Token != "". This leaves standalone short-token cache entries behind. GetTokenUserByShortToken() checks that cache first and then loads the user by ID, so the stale short token becomes usable again if the account status is restored to true. Relevant code paths: - internal/user/user.go - internal/user/user.go - internal/user/user.go - api/user/shorttoken.go - internal/middleware/middleware.go PoC This was verfied locally in an isolated environment with a temporary package-level harness that exercised the real token issuance,…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  5. High, CVSS 8.8GoAmendedPublished

    Nginx UI: nginx config directive denylist (ValidateConfigFile) is bypassable via same-line ";" separation → authenticated directive injection (RCE on the official image)

    CVE-2026-84316 · GHSA-cf23-7qxj-xmhr

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    config.ValidateConfigFile is the security control that blocks dangerous nginx directives (js, perl, loadmodule of njs/perl modules, user root). Its directive scanner is bypassable: it splits the config by newlines and inspects only the FIRST token of each line, but nginx separates directives with ;, not newlines. Putting a benign directive first and the blocked directive after a ; on the SAME line defeats every check. The include directive is also not on the denylist. As a result, an authenticated caller can inject the exact directives the hardening was meant to block, through EVERY path that calls the validator — POST /api/configs (add), the REST config modify endpoint (api/config/modify.go), the MCP nginxconfigmodify tool, and the site/stream save paths (internal/site/save.go, internal/stream/save.go). On deployments where nginx has the njs/perl module (the official uozi/nginx-ui Docker image ships ngxhttpjsmodule.so), this leads to code execution in the nginx worker; with…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  6. High, CVSS 8.3GoAmendedPublished

    Nginx UI OTP secure-session step-up is missing on sensitive mutation routes

    CVE-2026-84315 · GHSA-5v7c-xpfp-p65m

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    Reporter: Jagadesh Achanta Target: 0xJacky/nginx-ui Affected version / commit tested: - App version: 2.3.10 - Commit: 4948fba8744e82c3d7003f68ee164e9f49421066 - Disclosure channel: GitHub Private Vulnerability Reporting - Credential reference: cred:github-jagstack-gh-cli AI assistance disclosure This report was prepared by Jagadesh Achanta with assistance from OpenAI/Codex for public source review, local evidence collection, and report drafting. Summary Nginx UI has a short-lived OTP/passkey "secure session" step-up boundary for users with 2FA enabled. RequireSecureSession() rejects an OTP-enabled user's request unless the request includes a valid X-Secure-Session-ID issued after a fresh OTP/passkey verification. The project already applies this step-up middleware to sensitive operations such as: - Nginx config create/edit/rename/delete; - site save/delete/enable/disable/rename/duplicate; - stream save/delete/enable/disable/rename/duplicate; - settings save and protected secret…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  7. High, CVSS 8.7GoAmendedPublished

    Nginx UI: Account Takeover via Missing RequireSecureSession on User Management Endpoint

    CVE-2026-84314 · GHSA-2gc7-j998-5xx6

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    POST /api/users/:id allows any authenticated user to change any other user's password without RequireSecureSession (2FA verification). In contrast, the self password change endpoint POST /api/user/password correctly requires RequireSecureSession. This inconsistency enables any authenticated user to take over the initial admin account (user ID 1) by simply changing its password. Details nginx-ui enforces RequireSecureSession middleware on sensitive operations such as self password change (api/user/router.go:55), self profile update (api/user/router.go:54), settings modification (api/settings/router.go:12), and config file deletion/rename (api/config/router.go:16-21). However, the user management endpoint registered in InitManageUserRouter (api/user/user.go:31-68) is mounted on the g router group (router/routers.go:92) which only applies middleware.AuthRequired() and middleware.Proxy() — no RequireSecureSession(). As a result, POST /api/users/:id with a password field in the…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  8. High, CVSS 8.8GoAmendedPublished

    Nginx UI: MCP nginx_config_add Bypasses Directive Validation — Authenticated RCE

    CVE-2026-84318 · GHSA-9jww-cxg5-rj9m

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250506154222-1330888280a2, < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    The MCP tool nginxconfigadd writes nginx configuration files to disk and triggers an nginx reload without calling config.ValidateConfigFile. The identical flow in the REST API (POST /api/configs) does call that function and correctly rejects dangerous directives. An authenticated attacker can exploit this gap to write config files containing any blocked directive (perl, jsimport, loadmodule, user root, etc.), bypassing nginx-ui's entire security layer. On a server with the nginx Perl, njs, or Lua module loaded, this is post-authentication Remote Code Execution. Details api/config/add.go (line 46) calls config.ValidateConfigFile before writing: mcp/config/configadd.go (line 79) omits that call entirely and writes directly: config.ValidateConfigFile runs two checks: - ValidateConfigContent — rejects control characters, enforces encoding. - ValidateConfigDirectives — rejects a blocklist of dangerous directives: perl, perlmodules, perlrequire, perlset, jsimport, jsset, jscontent,…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  9. High, CVSS 8.8GoAmendedPublished

    Nginx UI: MCP nginx_config_add skips config directive validation → authenticated nginx directive injection (RCE on the official image)

    CVE-2026-84317 · GHSA-76pm-mq2q-9gcr

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    internal/config/validation.go (ValidateConfigFile) is a security control that blocks dangerous nginx directives — js, perl, loadmodule of the njs/perl modules, and user root. It is enforced on three of the four config-write paths: api/config/add.go, api/config/modify.go, and mcp/config/configmodify.go. The fourth path — the MCP tool nginxconfigadd (mcp/config/configadd.go) — does NOT call it: it writes the caller-supplied content straight to disk and reloads nginx. An authenticated MCP caller (or an MCP agent induced via prompt injection) can therefore inject exactly the directives the control is meant to block, leading to nginx code execution on deployments where the njs/perl module is available (e.g. the official Docker image). Root cause — an incomplete hardening patch Commit 3e411d38 ("Harden config write paths", 2026-04-21) introduced ValidateConfigFile and wired it into the config-write paths — but its changeset touched only: api/config/add.go (+6), api/config/modify.go…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  10. Medium, CVSS 6.3GoAmendedPublished

    Nginx UI: Auto backup name allows path traversal outside validated storage path

    CVE-2026-84320 · GHSA-jrq7-xrjx-pcfw

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260715121709-f92218e01054
    Fixed in
    1.9.10-0.20260715121709-f92218e01054· Vendor fix available
    Issue
    Nginx UI validates backuppath and storagepath against the administrator-defined backup.GrantedAccessPath boundary, but the final auto-backup output filename is built from the user-controlled auto-backup name without stripping path separators or .. components. An authenticated user who can create or modify an auto-backup task can set a name such as task/../../../escaped. The configured storagepath still passes validation because it is inside GrantedAccessPath, but the generated backup path escapes that storage directory when filepath.Join(storagepath, filename) resolves the embedded traversal sequence. This bypasses the documented backup path boundary and allows backup archives, and for encrypted configuration backups the adjacent .key file, to be written outside the intended storage directory with the Nginx UI process privileges. Affected Versions - Current dev branch commit checked: 4948fba8744e82c3d7003f68ee164e9f49421066 - Latest release checked: v2.3.10, published…

    Recommended action: Upgrade to 1.9.10-0.20260715121709-f92218e01054 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  11. High, CVSS 8.3GoAmendedPublished

    Nginx UI: MCP configuration tools bypass restricted directive validation and allow secondary authenticated users to execute NJS in Nginx worker context

    CVE-2026-84319 · GHSA-5r62-gj48-897x

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260703131214-23d1934099b0
    Fixed in
    1.9.10-0.20260703131214-23d1934099b0· Vendor fix available
    Issue
    The regular HTTP configuration API rejects restricted Nginx directives such as loadmodule, jsimport, and jscontent. However, the MCP configuration interface allows a secondary authenticated user to write and apply equivalent restricted configuration content. In the lab, this allowed the user to load ngxhttpjsmodule.so, import attacker-controlled JavaScript, reload Nginx, and execute NJS in the Nginx worker context. This is authenticated and is not OS command execution by itself. Affected component - /mcp - /mcpmessage - MCP tool: nginxconfigadd - Nginx configuration validation Impact A secondary authenticated user can bypass the restricted directive validation enforced by the HTTP API and execute attacker-controlled NJS inside the Nginx worker context. This may allow modification of Nginx runtime behavior, including responses, routing, headers, redirects, and request handling. Minimal PoC Preconditions - Attacker has a secondary authenticated Nginx UI account. - MCP is…

    Recommended action: Upgrade to 1.9.10-0.20260703131214-23d1934099b0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  12. High, CVSS 7.5GoAmendedPublished

    Nginx UI: Unauthenticated signed-request body staging can exhaust temporary storage

    CVE-2026-107805 · GHSA-j3hg-9rp3-5hw9

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20260729084040-acb59fdd81db, < 1.9.10-0.20260901043436-8c9b9a1aff21
    Fixed in
    1.9.10-0.20260901043436-8c9b9a1aff21· Vendor fix available
    Issue
    In Nginx UI versions 2.5.0 through 2.5.x, the node-signature authentication path staged an attacker-controlled request body in a temporary file and synchronized it to disk before validating the body digest and cryptographic signature. An unauthenticated remote client that can reach the API can provide syntactically valid signature metadata and cause storage and I/O consumption before the request is rejected. Impact Concurrent malicious requests can consume temporary filesystem capacity, disk I/O, and request-processing resources, potentially disrupting Nginx UI and other services that share the filesystem. The issue affects availability only; it does not bypass authentication and does not provide confidentiality or integrity impact. Deployment-specific reverse-proxy body limits, filesystem quotas, and concurrency limits may reduce practical impact. Remediation Upgrade to Nginx UI 2.6.0 or later. The fix authenticates signed request metadata before staging the body and…

    Recommended action: Upgrade to 1.9.10-0.20260901043436-8c9b9a1aff21 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  13. Medium, CVSS 5.3GoAmendedPublished

    Nginx UI: Bundled reverse proxy can bypass IP allowlists and enable shared login lockout

    CVE-2026-107804 · GHSA-9h23-53f4-q947

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20251005005631-6de168c9454, < 1.9.10-0.20260904075558-e30e331303fc
    Fixed in
    1.9.10-0.20260904075558-e30e331303fc· Vendor fix available
    Issue
    In Nginx UI versions 2.2.0 through 2.5.x, the official bundled reverse-proxy topology did not preserve the external client identity used by Gin. The backend treated the local proxy peer as the client because no trusted proxy was configured, while the proxy supplied the actual address in forwarding headers. Impact This has two distinct effects in bundled-proxy deployments: IP allowlist enforcement: management API requests forwarded by the bundled proxy were identified as loopback and could pass the loopback exception even when the external source was not in the configured allowlist. Protected management operations still required valid credentials; this did not grant unauthenticated administrator access. Login availability: failed login attempts from different external sources were attributed to one loopback address. An unauthenticated attacker could therefore trigger the shared temporary login-ban threshold and deny password or OTP login to other users behind the proxy until…

    Recommended action: Upgrade to 1.9.10-0.20260904075558-e30e331303fc (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  14. Critical, CVSS 9.0GoAmendedPublished

    Nginx UI: Authenticated Remote Code Execution via Backup Restore App Config Overwrite

    CVE-2026-107806 · GHSA-p393-cf76-4jmr

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20260421071512-7864e378f5cf, < 1.9.10-0.20260728074146-a467ed652591
    Fixed in
    1.9.10-0.20260728074146-a467ed652591· Vendor fix available
    Issue
    An authenticated nginx-ui user can call POST /api/restore, upload a forged encrypted backup, restore app.ini, set nginx command settings such as TestConfigCmd, and then trigger command execution with POST /api/nginx/test. This was validated on nginx-ui 2.3.11 2(523) 6c86e5a5 in the local Docker container uozi/nginx-ui:latest. Impact An authenticated user can overwrite nginx-ui application configuration and database state through restore, including protected settings that are normally not writable through the settings API. By setting nginx command fields in the restored app.ini, the attacker can execute commands in the nginx-ui runtime context. This affects confidentiality, integrity, and availability because the attacker can read or replace secrets, change node/JWT secrets, corrupt application state, and execute arbitrary commands. Affected Version / Environment - Version: nginx-ui 2.3.11 2(523) 6c86e5a5 - Deployment: local Docker, uozi/nginx-ui:latest - Base URL used in…

    Recommended action: Upgrade to 1.9.10-0.20260728074146-a467ed652591 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  15. High, CVSS 7.5GoAmendedPublished

    Nginx UI: Self-upgrade runs an unsigned binary verified only by a same-origin digest → RCE via a compromised mirror or MITM

    CVE-2026-107812 · GHSA-662p-52hx-cmh2

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250517140552-daee3ac7ade1, < 1.9.10-0.20260728114330-580585516dd8
    Fixed in
    1.9.10-0.20260728114330-580585516dd8· Vendor fix available
    Issue
    The self-upgrade downloads the release binary and its checksum (.tar.gz and .tar.gz.digest) through the SAME endpoint (version.GetUrl(), which is githubproxy or, by default, the project's cloud.nginxui.com mirror), and verifies the binary ONLY by comparing it to that digest: digestFileContent == DigestSHA512(tarName). Both the binary and the digest come from the same origin, and there is NO cryptographic signature / public-key verification. The downloaded binary then replaces the running executable (selfupdate.CommitBinary) and the process restarts, so the binary runs as the nginx-ui user (typically root). Because integrity rests only on a digest fetched from the same place as the binary, anyone who controls that download path can substitute a malicious binary plus a matching digest and obtain code execution as root on the next upgrade. Additionally, the githubproxy setting accepts http:// URLs, so the binary+digest can be fetched over cleartext. Affected code -…

    Recommended action: Upgrade to 1.9.10-0.20260728114330-580585516dd8 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  16. High, CVSS 8.1GoAmendedPublished

    Nginx UI: Authentication bypass: password login does not enforce a passkey-only second factor (2FA bypass)

    CVE-2026-107808 · GHSA-45gv-9wjv-xh7p

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250517140552-daee3ac7ade1, < 1.9.10-0.20260728074558-95cd21b70814
    Fixed in
    1.9.10-0.20260728074558-95cd21b70814· Vendor fix available
    Issue
    nginx-ui supports two second-factor methods — TOTP (OTP) and WebAuthn passkeys — and reports an account as 2FA-enabled when either is configured. However, the password login endpoint (POST /api/login) only enforces a second factor when a TOTP secret is present. An account that has registered a passkey but no TOTP is logged in after password verification alone — the passkey is never requested. This silently downgrades a passkey-protected account to single-factor (password-only) authentication. Details The account's 2FA policy treats passkeys as a valid factor (model/user.go): But the login handler only checks EnabledOTP() (api/user/auth.go, Login): No branch requires a WebAuthn assertion during password login when EnabledPasskey() is true. The root cause is the mismatch between the policy definition (Enabled2FA() = OTP or passkey) and the enforcement check (EnabledOTP() only). The same EnabledOTP()-only gating in RequireSecureSession() (internal/middleware/securesession.go)…

    Recommended action: Upgrade to 1.9.10-0.20260728074558-95cd21b70814 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  17. High, CVSS 8.8GoAmendedPublished

    Nginx-UI AuthRequired token cookie fallback enables CSRF against management APIs

    CVE-2026-107809 · GHSA-33rr-wq23-g6gg

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250517140552-daee3ac7ade1, < 1.9.10-0.20260728074433-a3999bd78a3b
    Fixed in
    1.9.10-0.20260728074433-a3999bd78a3b· Vendor fix available
    Issue
    Nginx-UI v2.4.3 stores the API JWT in a browser cookie named token and the AuthRequired middleware accepts that cookie as an authentication source. Because management endpoints are protected by AuthRequired and do not enforce a universal CSRF token or Origin/Referer check, a remote attacker can induce a logged-in administrator to submit cross-site state-changing requests. The attacker does not need to read the cross-origin response; the browser-sent cookie is enough to authenticate the request. Details The root cause is a trust-boundary failure between browser-managed cookies and API bearer-token authentication. In app/src/pinia/moudule/user.ts:25-35, the front end writes the JWT to a token cookie when the token changes. In internal/middleware/middleware.go:16-36, getToken first checks the Authorization header and token query parameter, then falls back to c.Cookie("token"). That fallback causes browser-initiated cross-site requests to carry a valid API credential…

    Recommended action: Upgrade to 1.9.10-0.20260728074433-a3999bd78a3b (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  18. High, CVSS 8.8GoAmendedPublished

    Nginx UI: Incomplete fix of CVE-2026-84315 - the api/cluster router was not - wrapped in RequireSecureSession, so those sensitive mutations run without OTP step-up

    CVE-2026-107813 · GHSA-h246-wpgf-vmq5

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250517140552-daee3ac7ade1, < 1.9.10-0.20260728074433-a3999bd78a3b
    Fixed in
    1.9.10-0.20260728074433-a3999bd78a3b· Vendor fix available
    Issue
    Incomplete fix of GHSA-5v7c-xpfp-p65m: the secure-session (OTP step-up) requirement added to the nginx, cert, dns, backup, site, and stream mutation routers was not applied to the parallel api/cluster router, so cluster node management and cluster-wide nginx reload/restart run with only a JWT and no step-up. An authenticated user whose JWT is stolen or persisted, but who does not hold a fresh secure-session, can perform cluster node CRUD (including reading and rewriting a node token secret) and trigger cluster-wide nginx reload/restart. Confirmed at HEAD 2cb7ee9102c9d87274de2fa104db804841d140a0. The defect GHSA-5v7c-xpfp-p65m required a fresh secure session (an OTP step-up beyond the JWT) for sensitive mutation routes. The fix wrapped the nginx, cert, dns, backup, site, and stream mutation handlers in middleware.RequireSecureSession() and added reload/restart to the MCP sensitive-tool list. It did not touch the physically separate api/cluster package, whose router registers…

    Recommended action: Upgrade to 1.9.10-0.20260728074433-a3999bd78a3b (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  19. High, CVSS 8.8GoAmendedPublished

    0xJacky/nginx-ui /api/nodes Leaks Cluster Node Tokens and Allows Cross-Node Impersonation as initUser

    CVE-2026-107811 · GHSA-32gc-wf3m-78w9

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250517140552-daee3ac7ade1, < 1.9.10-0.20260728091109-0ecbd106c37b
    Fixed in
    1.9.10-0.20260728091109-0ecbd106c37b· Vendor fix available
    Issue
    0xJacky/nginx-ui contains a high-severity trust-boundary failure between ordinary users and cluster node credentials. The source code shows that cluster node list and detail endpoints are reachable by ordinary authenticated users and return node objects containing the token field. That same token is also used as the X-Node-Secret shared credential for node-to-node authentication. When the middleware receives a correct node secret, it upgrades the request to initUser and bypasses the normal user-authentication path. As a result, any low-privileged authenticated user can first read a node token from /api/nodes and then impersonate a trusted node against a remote node's management API, achieving cross-node administrative authentication bypass. Details The root cause is a combination of sensitive credential exposure and improper trust elevation for node-to-node authentication. First, router/routers.go:87-105 mounts cluster.InitRouter(g) inside the shared /api authenticated route…

    Recommended action: Upgrade to 1.9.10-0.20260728091109-0ecbd106c37b (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  20. High, CVSS 8.8GoAmendedPublished

    Nginx UI: Node Secret Credential Exposure via URL Query Parameter

    CVE-2026-107807 · GHSA-pvgv-gcp7-v38g

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250517140552-daee3ac7ade1, < 1.9.10-0.20260728074433-a3999bd78a3b
    Fixed in
    1.9.10-0.20260728074433-a3999bd78a3b· Vendor fix available
    Issue
    1. Vulnerability Summary nginx-ui's Node.Secret is a master credential that bypasses all JWT/password authentication for the entire API. The application accepts this credential via a URL query parameter (?nodesecret=), causing it to be recorded in plaintext in HTTP access logs, reverse proxy logs, browser history, and HTTP Referer headers. Additionally, the official cluster configuration format embeds node secrets directly into URL query strings stored in app.ini and environment variables, creating a systemic credential exposure pattern across the entire cluster deployment model. An attacker who gains read access to any log aggregation system, proxy log, or configuration file can extract the node secret and obtain full, persistent, unauthenticated administrative access to the nginx-ui API — including reading TLS private keys, modifying nginx configurations, and (when chained with Bug #1) achieving OS-level code execution. --- 2. Root Cause Analysis 2.1 Node Secret Accepted as URL…

    Recommended action: Upgrade to 1.9.10-0.20260728074433-a3999bd78a3b (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  21. High, CVSS 8.1GoAmendedPublished

    Nginx UI: Backup restore follows crafted symlinks into the live Nginx configuration path before restore flags are applied

    CVE-2026-107810 · GHSA-p8v3-89rh-jxc7

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 1.9.10-0.20250517140552-daee3ac7ade1, < 1.9.10-0.20260728074146-a467ed652591
    Fixed in
    1.9.10-0.20260728074146-a467ed652591· Vendor fix available
    Issue
    An authenticated user who can create and restore a backup can craft a valid backup archive that causes the restore staging process to write attacker-controlled files into the live Nginx configuration path even when both restorenginx and restorenginxui are set to false. Details The restore flow always extracts the outer archive, verifies the manifest, decrypts nginx-ui.zip and nginx.zip, and extracts both inner archives before it decides whether RestoreNginx or RestoreNginxUI should be applied. The zip extractor explicitly allows absolute symlinks when the link target is under nginx.GetConfPath() or nginx.GetModulesPath(). Later regular-file entries are then created with os.OpenFile() on the symlinked path, which follows the symlink and writes into the live path. Relevant code paths: - internal/backup/restore.go - internal/backup/restore.go - internal/backup/restore.go - internal/backup/restore.go - api/backup/restore.go - api/backup/backup.go This means the restore trust…

    Recommended action: Upgrade to 1.9.10-0.20260728074146-a467ed652591 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)osv.dev (2)github.com (3)Source checked Evidence →
  22. High, CVSS 8.1GoPublished

    Nginx-UI: Unauthenticated First-Run Installer Allows Remote Initial Admin Claim

    CVE-2026-42221 · GHSA-h27v-ph7w-m9fp

    Affected
    • Go github.com/0xJacky/Nginx-UI >= 2.0.0, <= 2.3.5
    Fixed in
    2.3.8· Vendor fix available
    Issue
    An unauthenticated network attacker can claim the initial administrator account on a fresh nginx-ui instance during the first-run setup window. The public /api/install endpoint is reachable without authentication, and the request-encryption flow only protects payload confidentiality in transit; it does not authenticate who is allowed to perform installation. A remote attacker who reaches the service before the legitimate operator can set the admin email, username, and password, causing permanent initial-instance takeover. Details The vulnerable route is exposed publicly through the main API router. router/routers.go:61-70 mounts system.InitPublicRouter(root) under /api, and api/system/router.go:16-19 registers both GET /api/install and POST /api/install without AuthRequired(). The install handler only checks whether the instance is already installed and whether more than ten minutes have elapsed since startup. api/system/install.go:26-33 treats the instance as uninstalled…

    Recommended action: Upgrade to 2.3.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  23. High, CVSS 8.6GoPublished

    Nginx-UI: Cross-Site WebSocket Hijacking (CSWSH) via missing origin validation on all WebSocket endpoints

    CVE-2026-34403 · GHSA-78mf-482w-62qj

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260316053337-1a9cd29a3082
    Fixed in
    1.9.10-0.20260316053337-1a9cd29a3082· Vendor fix available
    Issue
    All WebSocket endpoints in nginx-ui use a gorilla/websocket Upgrader with CheckOrigin unconditionally returning true, allowing Cross-Site WebSocket Hijacking (CSWSH). Combined with the fact that authentication tokens are stored in browser cookies (set via JavaScript without HttpOnly or explicit SameSite attributes), a malicious webpage can establish authenticated WebSocket connections to the nginx-ui instance when a logged-in administrator visits the attacker-controlled page. Details Vulnerable Code Pattern Every WebSocket endpoint in the codebase uses the same unsafe upgrader configuration: Cookie-Based Authentication The Vue.js frontend stores JWT tokens as cookies without security attributes (app/src/pinia/moudule/user.ts): The backend middleware accepts tokens from cookies (internal/middleware/middleware.go): Affected Endpoints All WebSocket endpoints under the authenticated router group are vulnerable: | Endpoint | Impact | |---|---| | /api/nginx/detailstatus/ws | Leak…

    Recommended action: Upgrade to 1.9.10-0.20260316053337-1a9cd29a3082 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  24. High, CVSS 8.6GoPublished

    Nginx-UI: Disabled users retain full API access through previously issued bearer tokens

    CVE-2026-33031 · GHSA-x234-x5vq-cc2v

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260314152518-7b66578adb47
    Fixed in
    1.9.10-0.20260314152518-7b66578adb47· Vendor fix available
    Issue
    A user who was disabled by an administrator can use previously issued API tokens for up to the token lifetime. In practice, disabling a compromised account does not actually terminate that user’s access, so an attacker who already stole a JWT can continue reading and modifying protected resources after the account is marked disabled. Since tokens can be used to create new accounts, it is possible the disabled user to maintain the privilege. Details The application exposes an account-level disable control through the users management API. Login process correctly enforces that control: https://github.com/0xJacky/nginx-ui/blob/6ec542fd97abf2c5950f374f78a32938ad0030e6/internal/user/login.go#L29-L31 However, token-based authentication does not enforce the same check (This code validates token structure and expiry, but returns that user object without checking user.Status.):…

    Recommended action: Upgrade to 1.9.10-0.20260314152518-7b66578adb47 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  25. Critical, CVSS 9.4GoPublished

    nginx-ui Backup Restore Allows Tampering with Encrypted Backups

    CVE-2026-33026 · GHSA-fhh2-gg7w-gwpq

    Affected
    • Go github.com/0xJacky/Nginx-UI < 1.9.10-0.20260315015203-f61bcec547c0
    Fixed in
    1.9.10-0.20260315015203-f61bcec547c0· Vendor fix available
    Issue
    The nginx-ui backup restore mechanism allows attackers to tamper with encrypted backup archives and inject malicious configuration during restoration. Details The backup format lacks a trusted integrity root. Although files are encrypted, the encryption key and IV are provided to the client and the integrity metadata (hashinfo.txt) is encrypted using the same key. As a result, an attacker who can access the backup token can decrypt the archive, modify its contents, recompute integrity hashes, and re-encrypt the bundle. Because the restore process does not enforce integrity verification and accepts backups even when hash mismatches are detected, the system restores attacker-controlled configuration even when integrity verification warnings are raised. In certain configurations this may lead to arbitrary command execution on the host. The backup system is built around the following workflow: 1. Backup files are compressed into nginx-ui.zip and nginx.zip. 2. The files are…

    Recommended action: Upgrade to 1.9.10-0.20260315015203-f61bcec547c0 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →