Nginx UI: ユーザー管理エンドポイントにおける `RequireSecureSession` の欠落によるアカウント乗っ取り
### 概要
`POST /api/users/:id` は、認証されたユーザーであれば、`RequireSecureSession` (2段階認証) なしに、他のユーザーのパスワードを変更することを許可しています。 一方、自己パスワード変更のエンドポイントである `POST /api/user/password` は、正しく `RequireSecureSession` を要求しています。 この不整合により、認証されたユーザーは、初期の管理者アカウント (ユーザーID 1) のパスワードを変更するだけで、そのアカウントを乗っ取ることができます。
### 詳細
nginx-ui は、自己パスワード変更 (`api/user/router.go:55`)、自己プロファイル更新 (`api/user/router.go:54`)、設定の変更 (`api/settings/router.go:12`)、および設定ファイルの削除/リネーム (`api/config/router.go:16-21`) など、機密性の高い操作に対して `RequireSecureSession` ミドルウェアを適用しています。
しかし、`InitManageUserRouter` に登録されているユーザー管理エンドポイント (`api/user/user.go:31-68`) は、`g` ルーターグループ (`router/routers.go:92`) にマウントされており、このグループには `middleware.AuthRequired()` と `middleware.Proxy()` のみが適用され、**`RequireSecureSession()` は適用されていません**。
その結果、JSONボディに `password` フィールドを持つ `POST /api/users/:id` は、ターゲットユーザーのパスワードを、基本的なJWT認証のみで更新します。 ターゲットユーザーが2段階認証を有効にしている場合でも、2段階認証やセキュアセッションの検証は行われません。
攻撃の流れ:
1. 攻撃者は、任意のユーザーとして認証します (例: ユーザーID 2)。
2. 攻撃者は、`POST /api/users/1` に `{"password": "attacker-chosen"}` を送信します。
3. 管理者 (ユーザーID 1) のパスワードが変更されます。 既存のすべての管理者トークンが無効になります (`api/user/user.go:48-49`)。
4. 攻撃者は、新しいパスワードで管理者としてログインします。
5. 管理者アカウントがロックアウトされます。
### 実証
[poc.zip](https://github.com/user-attachments/files/26971275/poc.zip)
次の手順に進む前に、アップロードされた圧縮ファイルを展開してください。
1. docker compose up -d
2. python3 poc.py
<img width="501" height="55" alt="スクリーンショット 2026-04-22 午後10:26:29" src="https://github.com/user-attachments/assets/6562ede2-7c11-48da-b905-be9964f4f7b1" />
### 影響
- 認証されたユーザーであれば、他のユーザーのパスワードをすべて変更できます。初期管理者(ユーザーID 1)のパスワードも変更可能です。
- 管理者アカウントの完全な乗っ取りが可能。
影響を受けるパッケージ:
- go github.com/0xJacky/Nginx-UI: 影響を受けるバージョンは 1.9.10-0.20260703131214-23d1934099b0 未満、修正されたバージョンは 1.9.10-0.20260703131214-23d1934099b0。