## Summary
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 the same class of sensitive operations on the bare authenticated group.
The fixed sibling, api/nginx/router.go:
```go
o := r.Group("", middleware.RequireSecureSession()) // line 28
{
o.POST("nginx/reload", Reload) // line 30
o.POST("nginx/restart", Restart) // line 31
}
```
The missed router, api/cluster/router.go, registers every sensitive operation directly on r with no RequireSecureSession wrapper:
```go
nodeGroup := r.Group("nodes") // line 9, no step-up
{
nodeGroup.POST("", AddNode) // line 12
nodeGroup.POST("/:id", EditNode) // line 13
nodeGroup.DELETE("/:id", DeleteNode) // line 14
}
r.POST("nodes/reload_nginx", ReloadNginx) // line 17
r.POST("nodes/restart_nginx", RestartNginx) // line 18
r.POST("namespaces", AddNamespace) // line 22
r.POST("namespaces/:id", ModifyNamespace) // line 23
r.DELETE("namespaces/:id", DeleteNamespace) // line 24
```
Both routers mount on the same group in router/routers.go: `g := root.Group("/", middleware.AuthRequired(), middleware.Proxy())` (line 87); nginx.InitRouter(g) creates its own RequireSecureSession subgroup, cluster.InitRouter(g) does not. So the cluster routes inherit only AuthRequired and Proxy, exactly the pre-fix posture the advisory closed for the nginx routes. AuthRequired has no role gate, so any authenticated user reaches them.
## Attacker model and impact
An authenticated, OTP-enabled user who does not present a fresh X-Secure-Session-ID (the parent advisory's model: a stolen or persisted JWT used without the step-up). Such a user can: add/edit/delete cluster nodes (AddNode/EditNode store an AES-serialized node token, the secret used to control a remote node, so this reads back and rewrites a cross-node credential); trigger nodes/reload_nginx and nodes/restart_nginx across the cluster (the exact reload/restart action class the fix protected on the single-node path); and add/modify/delete/reorder namespaces.
Proof of concept: with a valid JWT but no fresh secure session, call POST /api/nodes (AddNode) or POST /api/nodes/reload_nginx. The nginx equivalent POST /api/nginx/reload returns the secure-session challenge; the cluster route succeeds.
## Verification
Source-verified at HEAD: the nginx router wraps reload/restart in RequireSecureSession, the cluster router registers node/namespace/reload/restart directly on the group with no such wrapper, and both mount on the AuthRequired+Proxy-only group. I did not stand up a live nginx-ui.
## Suggested fix
Wrap the cluster router's mutation handlers (node CRUD, nodes/reload_nginx, nodes/restart_nginx, namespace CRUD) in middleware.RequireSecureSession(), mirroring api/nginx/router.go. Secondary lower-confidence items worth checking in the same pass: the system/restart handler, the core-upgrade websocket, and the upstream socket PUT also appear to run without the step-up (I did not fully trace these).
nginx-ui versions 2.0.0 up to but not including 2.5.0 have a vulnerability in their self-upgrade mechanism where the binary and its checksum are downloaded from the same source without cryptographic signature verification. This allows an attacker controlling the download source or performing a man-in-the-middle attack on an HTTP proxy to substitute a malicious binary and matching digest, resulting in root code execution upon upgrade. The upgrade process replaces the running executable and restarts it as root. The vulnerability arises because integrity is only checked by comparing the binary's digest to a digest file fetched from the same origin, and the github_proxy setting accepts HTTP URLs, enabling cleartext interception. No official patch or fix is indicated in the provided data.
German authorities have arrested a Russian national suspected to be a core member of the Qilin ransomware group following extradition from Japan. This arrest targets a key individual allegedly involved in ransomware operations attributed to Qilin.
Insertion of sensitive information into log file in AWS Tools for PowerShell before 5.0.306 might allow local users to recover an IAM user's cleartext AWS Management Console password from command output and log artifacts.
To remediate this issue, users should upgrade to version 5.0.306 or later. After upgrading, review PowerShell transcripts and log stores for previously disclosed passwords and rotate any affected IAM console passwords.
A vulnerability in 0xJacky's nginx-ui versions 2.0.0 through 2.4.x allows authenticated users to access sensitive node tokens via specific API endpoints. These tokens can be used to bypass cross-node authentication, enabling impersonation of trusted nodes within the cluster. This can expose sensitive management operations such as configuration synchronization and service restart. The issue is resolved in version 2.5.0.
A vulnerability in Netcore B11 Enterprise-level full Gigabit 9-port shop wireless router version 1.3.241114.024540 and earlier allows a remote attacker to obtain sensitive information without authentication. The issue has a high severity rating with a CVSS score of 7.5, indicating significant confidentiality impact but no integrity or availability impact. No patch or remediation details are currently provided.
Apache Camel Karavan versions from 4.0.0 up to but not including 4.22.1 contain an improper input validation vulnerability. This flaw allows an authenticated user of any role to deploy arbitrary Kubernetes resources by submitting a crafted kubernetes.yaml file. The vulnerability arises because Karavan applies all resources in the deployment file without restricting resource kinds, rejecting security-sensitive pod options, or pinning the namespace. This can lead to the creation of privileged pods and other risky configurations within the cluster. The issue is fixed in version 4.22.1.
Apache Camel Karavan versions from 3.18.0 up to but not including 4.22.1 contain a path traversal vulnerability. This flaw allows an authenticated user to supply a project file name containing '../' sequences, causing files to be written outside the intended project directory. Exploitation can lead to overwriting application configuration or classpath files, enabling code execution within the Karavan container. The issue is fixed in version 4.22.1.
CVE-2026-107810 is a high-severity vulnerability in 0xJacky's nginx-ui versions from 2.0.0 up to but not including 2.5.0. It involves improper link resolution before file access in the backup and restore functionality, allowing an authenticated user with backup creation and restoration privileges to inject malicious symlinks. This can lead to persistent configuration injection or denial of service. The issue is fixed in version 2.5.0.
Use of Client-Side authentication vulnerability in Hayat Health Facilities Inc. (Hayat Hospital) Hayat Mobile allows Authentication Bypass.
This issue affects Hayat Mobile: from 3.3.0 before 3.4.0.
## Summary
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 automatically. The route group in `router/routers.go:87-110` applies `middleware.AuthRequired()` to many management modules, including `config.InitRouter`, `nginx.InitRouter`, `settings.InitRouter`, and backup-related handlers. For accounts without OTP/Passkey, `RequireSecureSession` does not provide a universal second factor for all state-changing operations. A representative sink is `api/config/add.go:68-78`, where an authenticated request writes Nginx configuration with `os.WriteFile` and then calls `nginx.Control(nginx.Reload)`. CORS does not mitigate this issue because preventing cross-origin response reads does not prevent cross-site form or no-cors requests from being sent with cookies.
Core vulnerable code path:
```typescript
// app/src/pinia/moudule/user.ts:25-35
watch(token, v => {
if (v) {
cookies.set('token', v, getCookieOptions(86400))
if (!shortToken.value) {
void fetchShortToken()
}
}
else {
cookies.remove('token', { path: '/' })
shortToken.value = ''
}
})
```
The front end stores the authentication token in a `token` cookie. The cookie is created client-side and is not shown here as HttpOnly; it becomes the credential that the back end later accepts through cookie fallback.
```go
// internal/middleware/middleware.go:16-36
// getToken from header, cookie or query
func getToken(c *gin.Context) (token string) {
if token = c.GetHeader("Authorization"); token != "" {
return
}
if token = c.Query("token"); token != "" {
if len(token) > 16 {
// Long token (base64 encoded JWT)
tokenBytes, _ := base64.StdEncoding.DecodeString(token)
return string(tokenBytes)
}
// Short token (16 characters)
return token
}
if token, _ = c.Cookie("token"); token != "" {
return token
}
return ""
}
```
`getToken` accepts the `token` cookie as an authentication credential after checking the header and query parameter. That behavior lets a browser-sent cookie authenticate state-changing API requests triggered from another origin.
```go
// router/routers.go:87-110
// Authorization required and not websocket request
g := root.Group("/", middleware.AuthRequired(), middleware.Proxy())
{
debug.InitRouter(g)
user.InitUserRouter(g)
analytic.InitRouter(g)
user.InitManageUserRouter(g)
nginx.InitRouter(g)
sites.InitRouter(g)
streams.InitRouter(g)
config.InitRouter(g)
template.InitRouter(g)
certificate.InitCertificateRouter(g)
certificate.InitDNSCredentialRouter(g)
certificate.InitAcmeUserRouter(g)
dnsapi.InitRouter(g)
system.InitPrivateRouter(g)
settings.InitRouter(g)
llm.InitRouter(g)
cluster.InitRouter(g)
notification.InitRouter(g)
external_notify.InitRouter(g)
backup.InitAutoBackupRouter(g)
nginxLog.InitRouter(g)
upstream.InitHTTPRouter(g)
```
Many management modules, including Nginx, configuration, settings, backup, and user management, are placed behind `AuthRequired`. The cookie fallback therefore protects high-impact state-changing routes, not only read-only endpoints.
```go
// api/config/add.go:68-78
err = os.WriteFile(path, []byte(content), 0644)
if err != nil {
cosy.ErrHandler(c, err)
return
}
res := nginx.Control(nginx.Reload)
if res.IsError() {
res.RespError(c)
return
}
```
This representative sink shows why the CSRF is high impact: once authenticated through the cookie fallback, a request can write Nginx configuration content and trigger a reload.
## POC
Prerequisites: an administrator is logged in to Nginx-UI and has a browser `token` cookie; the administrator account has not enabled OTP/Passkey, or the chosen target endpoint does not require secure-session proof; the attacker knows the Nginx-UI management URL and can induce the administrator to visit an attacker-controlled page. Reproduction: (1) Host an attacker page at `GET /csrf.html` that automatically submits a cross-site request to the victim instance. (2) The page submits `POST /api/configs`
## Summary
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`):
```go
func (u *User) EnabledOTP() bool { return len(u.OTPSecret) != 0 }
func (u *User) EnabledPasskey() bool { /* true if a passkey row exists */ }
func (u *User) Enabled2FA() bool { return u.EnabledOTP() || u.EnabledPasskey() }
func (u *User) AfterFind(_ *gorm.DB) error {
u.EnabledTwoFA = u.Enabled2FA() // exposed to the UI as `enabled_2fa`
return nil
}
```
But the login handler only checks `EnabledOTP()` (`api/user/auth.go`, `Login`):
```go
u, err := user.Login(json.Name, json.Password)
...
if u.EnabledOTP() { // <-- only TOTP is enforced
if json.OTP == "" && json.RecoveryCode == "" {
c.JSON(http.StatusOK, LoginResponse{Message: "The user has enabled 2FA", Code: Enabled2FA}) // 199
user.BanIP(clientIP)
return
}
if _, err = user.VerifyOTP(u, json.OTP, json.RecoveryCode); err != nil { /* ... */ }
secureSessionID = user.SetSecureSessionID(u.ID)
}
// Passkey-only accounts fall through to here and receive a full session token:
accessToken, err := user.GenerateJWT(u)
```
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/secure_session.go`) means passkey-only users are also
exempted from step-up on sensitive actions.
## Proof of Concept
Tested against nginx-ui built from source (`go build -tags unembed`) on
`127.0.0.1:9000`, with WebAuthn configured and a victim account that has a
registered passkey and **no** TOTP. The vulnerable code is identical on the
production `main` branch (`api/user/auth.go` `Login` gates on `u.EnabledOTP()`
only; verified at commit `6c86e5a`, 2026-05-17).
Account state advertised by `GET /api/2fa_status`:
```json
{"enabled":true,"otp_status":false,"passkey_status":true, ...}
```
Attacker logs in with **password only** (`POST /api/login`, encrypted params as
the client normally sends):
```
HTTP 200
{"message":"ok","code":200,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...."}
```
`code: 200` + a valid JWT = an authenticated session, with the passkey never
used. For comparison, the identical account with a TOTP secret instead correctly
returns the second-factor challenge:
```
HTTP 200
{"message":"The user has enabled 2FA","code":199}
```
| Account state | `POST /api/login` (password only) |
|---|---|
| Passkey registered, no TOTP | `code 200` + JWT — **2FA NOT enforced** |
| TOTP registered | `code 199` — 2FA challenge enforced |
This isolates the defect: the login path enforces OTP but ignores passkeys.
## Impact
- Any account protected **only** by a passkey is reduced to password-only
authentication. An attacker who obtains the password (phishing, reuse, leak)
gains full access despite the registered security key.
- In nginx-ui all authenticated users are effectively administrators and the
terminal feature grants a host shell, so account takeover leads to full
control of the managed nginx instance / host.
- Users are given a false sense of security: the UI shows the account as
2FA-enabled while the second factor is not enforced at login.
## Remediation
- Gate the second-factor decision on `u.Enabled2FA()` (not `u.EnabledOTP()`) in
`Login`, in both SSO callbacks, and in `RequireSecureSession()`.
- For a passkey-only user logging in with a password, return a
"passkey assertion required" challenge and complete login only after a
successful WebAuthn assertion (the `begin_passkey_login` / `finish_passkey_login`
flow already exists and should be required as the second step).
- Centralize session-token issuance so no login entry point can skip the 2FA
decision.
## Affected components
- `api/user/auth.go` — `Login`
- `model/user.go` — `EnabledOTP`, `EnabledPasskey`, `Enabled2FA`, `AfterFind`
- `api/user/2fa.go` — `get2FAStatus`
- `internal/middleware/secure_session.go` — `RequireSecureSession`
SmarterMail before build 9777 has a privilege escalation vulnerability due to insufficient session expiration. JWT access and refresh tokens embed a role claim that is not revalidated upon token refresh. This allows attackers to replay stale refresh tokens issued before an administrator's role demotion to regain higher privileges until token expiry.
Allocation of resources without limits or throttling (CWE-770) during Java object deserialization in Google Guava versions 4.0 through 33.7.1 allows an attacker to cause a Denial of Service via OutOfMemoryError. When deserializing CompactHashMap, CompactHashSet, or MapMakerInternalMap instances, Guava eagerly allocates an array based on a caller-specified size parameter without throttling, permitting memory exhaustion from crafted serialization streams.
SmarterMail versions before build 9777 contain a stored cross-site scripting (XSS) vulnerability. This flaw allows remote attackers to inject executable scripts by embedding payloads inside a <style> element nested within MathML foreign content, which bypasses the custom HTML sanitizer. Exploitation occurs when a crafted calendar (iCal) message with an <img> tag containing an onerror event is opened in the recipient's webmail session, leading to script execution and potential data exfiltration despite the Content-Security-Policy in place.
SmarterMail versions before build 9777 contain a remote code execution vulnerability that allows attackers with SysAdmin-scoped access tokens to bypass script directory containment controls. By provisioning a new mail domain with a crafted FileStore root path, attackers can upload malicious scripts that execute with SYSTEM-level privileges, resulting in a reverse shell. This vulnerability is identified as CVE-2026-104082 and has a high severity rating.
ILIAS versions before 9.24, 10.12, and 11.5 have an unrestricted file upload vulnerability in the QTI question import image handling component. Authenticated users with question pool import rights can upload crafted archives that write executable files, including .htaccess and PHP files, to web-accessible directories. This allows remote code execution as the web server user.
ruoyi-ai versions 3.0.0 through 3.1.0 have a missing authorization vulnerability that allows authenticated users to delete workflows owned by other users. This occurs because the softDelete() function bypasses the ownership check, enabling deletion via the POST /workflow/del/{uuid} endpoint when supplying workflow UUIDs obtained from GET /workflow/search.
ruoyi-ai versions 3.0.0 through 3.1.0 have a missing authorization vulnerability in the GET /workflow/search endpoint. Authenticated non-admin users can access this endpoint, which does not filter by owner or public status, allowing them to view private workflows of other users within the same tenant. The exposed data includes workflow UUIDs and full node and edge configurations. The vulnerability has a medium severity with a CVSS 4.0 score of 5.3.
MOVO versions 0.1.0 through 0.2.3 contain an authorization bypass vulnerability in the chat-api document endpoints. Authenticated users can exploit this flaw by supplying arbitrary object paths to access or overwrite other users' private documents and presentation blueprints. This vulnerability allows reading and modification of sensitive data without proper authorization.