Xen Orchestra の認証バイパスが悪用されホストを掌握(VSA-2026-062)
空の JSON オブジェクトを authenticationToken Cookie に入れると Xen Orchestra の認証を回避して管理者権限を取得できます。6.9.2 が修正します。
要点
authenticationTokenCookie に入れた空の JSON オブジェクトにより、Xen Orchestra は要求を認証済み管理者のものとして扱います。トークン検索はオブジェクトを受け取り、条件なしのクエリとして扱い、保存済みの最初のトークンを返します。- 安定版チャネルの 6.9.2 より前、最新版チャネルの 6.10.1 より前の Xen Orchestra が影響を受け、Xen Orchestra Appliance も含まれます。
xo-serverパッケージは 5.211.2 と 5.213.1 です。 - ベンダーはこの欠陥を重大と評価し、実際に悪用されていると述べています。CVE は割り当てられておらず、2026 年 11 月 11 日時点で CISA の Known Exploited Vulnerabilities カタログにも登録されていません。
- 6.9.2 または 6.10.1、あるいは
xo-server5.211.2 または 5.213.1 に更新してください。更新できない場合は、プロキシで空のトークン Cookie をブロックし、インスタンスをインターネットから外してください。
影響を受けますか?
次の条件がすべて当てはまる場合に影響を受けます。
- 安定版チャネルで 6.9.2 より前、または最新版チャネルで 6.10.1 より前の Xen Orchestra を実行している。Xen Orchestra Appliance も影響を受けます。
- 攻撃者が REST API に到達できる。脆弱な経路は
authenticationTokenCookie を読む REST 認証ミドルウェアです。 - インスタンスのトークンコレクションに、有効期限切れでない認証トークンが少なくとも 1 つある。トークンはユーザーがサインインしてログイン状態を維持することを選ぶたびに作成されるため、ほとんどの稼働中の配備に存在します。
ベンダーは、欠陥は XCP-ng ではなく Xen Orchestra にあると述べています。Xen Orchestra が管理対象プールの管理者資格情報を保持するため、影響はプールに及びます。侵害されたコンソールは、管理するすべてのホストでコマンドを実行できます。
Xen Orchestra は、XenServer のオープンソース代替である XCP-ng の管理コンソールです。プロジェクトのリポジトリは GitHub で 998 個のスターを獲得しており、コミュニティのコンテナイメージ ronivay/xen-orchestra は Docker Hub で 2,777,836 回取得されています。これはコンソールを実行する配備の多さを示す手がかりです。
| チャネル | 影響を受けるバージョン | 修正済みバージョン |
|---|---|---|
| 安定版 | 6.9.2 より前の Xen Orchestra、5.211.2 より前の xo-server |
Xen Orchestra 6.9.2、xo-server 5.211.2 |
| 最新版 | 6.10.1 より前の Xen Orchestra、5.213.1 より前の xo-server |
Xen Orchestra 6.10.1、xo-server 5.213.1 |
xo-server パッケージのバージョンを確認します。ソースからインストールした場合は、リポジトリのルートで次を実行します。
node -p "require('./packages/xo-server/package.json').version"
npm ls xo-server -g --depth=0
Xen Orchestra Appliance では、Web インターフェースの About ページを開き、Xen Orchestra のバージョンを確認します。ベンダーは勧告で修正済みの xo-server バージョンも公開しています。バージョンが 5.211.2 または 5.213.1 なら修正済みで、それより前の番号は影響を受けます。
修正方法
Xen Orchestra を安定版チャネルでは 6.9.2 に、最新版チャネルでは 6.10.1 に更新し、サービスを再起動します。ソースからのインストールは最新の master に更新して再ビルドしてください。
- 安定版チャネルでは、
xo-server5.211.2 を含む Xen Orchestra 6.9.2 に更新します。 - 最新版チャネルでは、
xo-server5.213.1 を含む Xen Orchestra 6.10.1 に更新します。 - ソースからのインストールでは、最新の
masterを取得し、通常のインストールとビルドの手順を実行してxo-serverを再起動します。 - 「影響を受けますか?」のコマンドで新しい
xo-serverバージョンを確認します。 - アプライアンスを使っている場合は、ベンダーの更新を適用し、About ページが 6.9.2 または 6.10.1 を示すことを確認します。
更新できない場合は、インスタンスをインターネットから外し、プロキシで空のトークンをブロックします。ベンダーは 3 つの緩和策を挙げています。
- Xen Orchestra を専用の管理ネットワークに置き、インターネットに公開しない。
- ベンダーがキャンペーンに関連付ける IP アドレスと Tor ドメインをブロックする。一覧は「侵害されたかどうかを確認するには?」にあります。
authenticationToken=j:{}とauthenticationToken=j:%7B%7Dを拒否する WAF またはリバースプロキシのルールを追加する。ベンダーは正規表現ルールが他のエンコーディングで回避され得ると警告しているため、暫定措置として扱ってください。
侵害の兆候が見つかった場合は、コンソールが到達できるすべての資格情報をローテーションします。プールシークレット、ホストの root パスワード、ユーザーアカウント、OTP シークレット、バックアップ先の資格情報、メールサーバーのパスワードが含まれます。ベンダーは、侵害が確認された後の完全な再インストールを推奨しています。清掃だけではバックドアが残らないことを保証できないためです。
根本原因は何ですか?
REST API は cookie-parser ミドルウェアで Cookie を解析し、このミドルウェアは j: 接頭辞を JSON として解釈します。authenticationToken=j:%7B%7D という Cookie 値は空のオブジェクト {} にデコードされます。REST ミドルウェアはそのオブジェクトをトークンとして認証プロバイダーに渡します。
async #authenticateUser(req) {
const { cookies, ip } = req
const token = cookies.authenticationToken ?? cookies.token
if (!token) {
throw invalidCredentials()
}
const { user } = await this.#app.authenticateUser({ token }, { ip })
プロバイダーは値が真実かどうかだけを確認します。空のオブジェクトは真実なので、要求は続行されます。
this.registerAuthenticationProvider(async ({ token: tokenId }, { ip } = {}) => {
if (!tokenId) {
return
}
try {
const token = await app.getAuthenticationToken(tokenId)
getAuthenticationToken は文字列、または id フィールドを持つオブジェクトを想定しています。型を確認せずに properties.id を読むため、空のオブジェクトは undefined を生成します。
async getAuthenticationToken(properties) {
const id = typeof properties === 'string' ? properties : properties.id
const token = await this._getAuthenticationToken(id, properties)
_getAuthenticationToken は、オブジェクトが存在する場合に元のオブジェクトをトークンコレクションへ渡します。
async _getAuthenticationToken(id, properties) {
const token = await this._tokens.first(properties ?? id)
コレクションの first({}) は空のオブジェクトを条件なしのクエリとして扱い、保持する最初のトークンを返します。そのトークンが有効期限内であれば、プロバイダーは要求をトークンの所有者として認証します。攻撃者は資格情報を知る必要がなく、オブジェクト自体がレコードを選択します。
どのように悪用されますか?
- 攻撃者は
authenticationToken=j:%7B%7D(またはauthenticationToken=j:{})という Cookie を付けて Xen Orchestra の REST API に HTTP 要求を送ります。 cookie-parserはj:の値を空のオブジェクト{}にデコードします。- REST ミドルウェアは
{ token: {} }を認証プロバイダーに渡します。プロバイダーの真偽チェックはオブジェクトを受け入れます。 getAuthenticationTokenはproperties.idを読み、これがundefinedになるため、元のオブジェクトをトークンコレクションへ転送します。- コレクションの
first({})が最初のトークンを返します。プロバイダーは有効期限を確認し、要求をそのトークンの所有者として認証します。 - 攻撃者は得られたセッションで
/rest/v0/users/me/authentication_tokensを呼び、再利用可能なログイントークン ID を受け取ります。 - 攻撃者は管理者セッションを使って設定を変更し、管理対象プールでコマンドを実行し、XCP-ng ホストに root として到達します。
ベンダーは、このエクスプロイトが管理対象プールでの任意コード実行と、XCP-ng ノードの root としての完全な掌握につながると述べています。Cookie のパターン以外の正確な要求手順は公開しておらず、以下の指標はキャンペーンのものであり、完全な検出手法ではありません。
攻撃の流れは?
空の JSON オブジェクトがトークン識別子を置き換え、トークンコレクションが最初のレコードを返し、要求が管理対象ホストに到達する管理者セッションになります。
文字列チェックなし"] D --> E["コレクションの first({}) が
最初のトークンを返す"] E --> F["トークン所有者としてのセッション
通常は管理者"] F --> G["管理対象プールと
XCP-ng ホストでコマンド実行"]
攻撃者に何ができますか?
REST API に到達した攻撃者は、有効期限切れでない最初のトークンの所有者として認証できます。実際には管理者です。そのセッションで管理者専用の REST ルートを呼べるためです。
影響には次のものがあります。
- Xen Orchestra の設定、ユーザー、認証トークンの読み取りと変更。
- Xen Orchestra のホストアクセスを通じた管理対象プールでのコマンド実行。
- ベンダーが説明する XCP-ng ノードの root としての掌握。
- プロキシ、バックアップ先(NFS、S3、Azure、SMB)、root アカウント、プールシークレット、ユーザーアカウント、OTP シークレット、メールサーバー設定の構成と資格情報の収集。
条件は「影響を受けますか?」と同じです。影響を受ける Xen Orchestra のバージョン、攻撃者から到達できる REST API、コレクション内の有効期限切れでないトークンが少なくとも 1 つあることです。ベンダーは実際に悪用されていると述べているため、インターネットに公開されたインスタンスは、トークンを見つける前から露出しているものとして扱ってください。
修正が機能する理由
修正はトークン識別子をコレクションに届く前に検証し、検証済みのフィールドだけからクエリを構築します。文字列チェックを追加し、検索を変更します。
+const isNonEmptyString = value => typeof value === 'string' && value.length !== 0
+
export default class {
@@
this.registerAuthenticationProvider(async ({ token: tokenId }, { ip } = {}) => {
- if (!tokenId) {
+ if (!isNonEmptyString(tokenId)) {
return
}
@@
- async _getAuthenticationToken(id, properties) {
- const token = await this._tokens.first(properties ?? id)
+ async _getAuthenticationToken(id, userId) {
+ if (!isNonEmptyString(id) || (userId !== undefined && !isNonEmptyString(userId))) {
+ return
+ }
+
+ // build the query from validated fields only, never forward caller-supplied objects
+ const token = await this._tokens.first(userId === undefined ? id : { id, user_id: userId })
getAuthenticationToken は入力から id と user_id だけを取り出し、その値を非公開の検索に渡します。{} にデコードされる Cookie は、データベースへのクエリが実行される前に文字列チェックで失敗します。有効な文字列トークンは引き続き動作し、複合的な { id, user_id } 検索は維持されます。攻撃者がオブジェクトに追加した余分なキーは無視されます。
修正は説明された経路に対して完全です。ベンダーの勧告は、REST API、サインイン経路、JSON-RPC の session.signIn メソッドが文字列でない空のトークン ID を拒否するようになったと述べています。独自のオブジェクトでトークンプロバイダーを呼ぶサードパーティコードは対象外なので、インスタンスをインターネットから外したままにしてください。
侵害されたかどうかを確認するには?
ベンダーは、認証されていないアクセスが成功してもログ項目は残らないと述べているため、パケットキャプチャが最も直接的な確認方法です。Xen Orchestra ホストまたはそのリバースプロキシでトラフィックを取得し、エンコードされた形式を含めて Cookie パターンを検索します。
tcpdump -i any -A -s 0 'tcp port 80 or tcp port 443' | grep -iE 'authenticationToken=j:(%7B%7D|\{\})'
grep -iE 'authenticationToken=j:(%7B%7D|\{\})' /var/log/nginx/access.log
同じ要求はベンダーの指標では authenticationToken=j:%7B%7D または authenticationToken=j:{} として現れます。一致は手がかりです。正規のクライアントは空のオブジェクトをトークンとして送るべきではありません。
XCP-ng ホストでキャンペーンの痕跡を確認します。
xe vm-list params=name-label,platform | grep -B1 'hvm_serial: file'
zgrep -- '-serial file:' /var/log/xensource.log*
ls -la /etc/ld.so.preload /.ustar* /etc/cron.d/zz-ustar*
ベンダーの指標には、pivot2 という名前の仮想マシン、hvm_serial: file パラメーターで構成された VM、/etc/cron.d/zz-ustar2、/etc/cron.d/zz-ustar、/.ustar5、/.ustar6 のファイルが含まれます。また、IP アドレス 91.211.251.112、193.148.56.72、37.221.208.216、45.66.35.11、64.65.0.120、64.65.62.160、89.47.51.90、92.60.37.247 と、Tor ドメイン ustar3rqxgnskzgnwkgpofgtvxevm6cx3lxdbwt4mndtveqyaohid.onion も挙げています。
これらが見つかった場合は、コンソールが到達できるすべての資格情報をローテーションし、インスタンスを再構築します。ベンダーは、清掃だけではすべてのバックドアの除去を保証できないと述べています。
年表
- 2026-11-10 08:29 UTC: 修正コミット
50166fe3が pull request #10748 としてマージされます。 - 2026-11-10: Vates が VSA-2026-062 と修正済みの Xen Orchestra 6.9.2、6.10.1 を公開します。
- 2026-11-10: ベンダーが記載の IP アドレスと Tor ドメインからの実際の悪用を報告します。
よくある質問
CVE はありますか?
2026 年 11 月 11 日時点で CVE は割り当てられていません。ベンダーは問題を VSA-2026-062 として追跡しており、勧告が正式な記録です。CVE がないことは緊急性を下げません。ベンダーは実際に悪用されていると述べています。
XCP-ng ホストに直接影響しますか?
欠陥は Xen Orchestra にあり、XCP-ng ホストのソフトウェアにはありません。ホストが危険なのは、Xen Orchestra が特権資格情報でそれらを管理するためです。コンソールを掌握した攻撃者はそのアクセスを使ってホストでコマンドを実行できるため、ベンダーはノードの完全な掌握と説明しています。
どのバージョンをインストールすべきですか?
安定版チャネルでは Xen Orchestra 6.9.2、最新版チャネルでは 6.10.1 をインストールします。ソースからのインストールでは最新の master に更新し、xo-server が 5.211.2 または 5.213.1 であることを確認します。アプライアンスの更新にも同じ修正が含まれます。
代わりにプロキシで Cookie をブロックできますか?
authenticationToken=j:{} と authenticationToken=j:%7B%7D を拒否するルールはキャンペーンの要求をブロックしますが、ベンダーは狭い正規表現が他のエンコーディングで回避され得ると警告しています。更新までの間だけ使い、インスタンスをインターネットから外したままにしてください。
ゼロデイとして悪用されましたか?
ベンダーは実際に悪用されていると述べていますが、活動の開始時期や攻撃が修正より前だったかは述べていません。脆弱性がゼロデイとして使われたかも述べていません。露出期間は不明として扱い、記載の痕跡をホストで確認してください。
侵害後に何をローテーションすべきですか?
アプライアンスが到達できるすべての資格情報をローテーションします。プールシークレット、ホストの root パスワード、Xen Orchestra のユーザーアカウント、OTP シークレット、プロキシ設定、NFS、S3、Azure、SMB のバックアップ先資格情報、メールサーバーのパスワードです。ローテーション後、正常なイメージからアプライアンスを再構築します。
Ostorlab で公開された Xen Orchestra コンソールを見つける
Ostorlab の攻撃対象領域の検出は、組織内のインターネットに公開されたホストを一覧化し、修正前にどの Xen Orchestra コンソールと管理インターフェースがネットワーク外から応答しているかを確認できます。一覧を使って、管理ネットワークに置くべきコンソールを見つけ、まだ公開されているものの優先順位を付けてください。
参考資料
- Vates の勧告 VSA-2026-062: https://docs.vates.tech/security-advisories/advisories/2026/vates-sa-2026-062/(2026 年 11 月 11 日確認)
- 修正 pull request #10748: https://github.com/vatesfr/xen-orchestra/pull/10748(2026 年 11 月 11 日確認)
- 修正コミット 50166fe3: https://github.com/vatesfr/xen-orchestra/commit/50166fe3a49c02069d35ba9046ca4a1f77f4e11d(2026 年 11 月 11 日確認)
- 親コミットの脆弱な
authentication.mjs: https://github.com/vatesfr/xen-orchestra/blob/724402733b2381d93372db0183e21df9d2c457f7/packages/xo-server/src/xo-mixins/authentication.mjs(2026 年 11 月 11 日確認) - 親コミットの脆弱な
rest-api.mjs: https://github.com/vatesfr/xen-orchestra/blob/724402733b2381d93372db0183e21df9d2c457f7/packages/xo-server/src/xo-mixins/rest-api.mjs(2026 年 11 月 11 日確認) - Xen Orchestra リポジトリ: https://github.com/vatesfr/xen-orchestra(2026 年 11 月 11 日確認)
- コミュニティの Xen Orchestra コンテナイメージ: https://hub.docker.com/r/ronivay/xen-orchestra(2026 年 11 月 11 日確認)