CVE-2026-63030
CVE-2026-63030 Vulnerability Report — WordPress REST API Batch Route Confusion (WP2Shell RCE)
概要
| 項目 | 内容 |
|---|---|
| CVE番号 | CVE-2026-63030 |
| 公開日 | 2026-07-17 |
| 最終更新 | 2026-07-18 |
| CVSS v3.1 | 9.8 (Critical) — WPScan採点 |
| CVSS Vector (WPScan) | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CVSS Vector (CISA-ADP) | 7.5 (High) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-436 (Interpretation Conflict) |
| EPSS | 【情報不足】NVD未算出時点 |
| CISA KEV | 【要確認】2026-07-18時点では未登録 |
| GHSA | GHSA-ff9f-jf42-662q (Critical) |
| 関連CVE | CVE-2026-60137 (GHSA-fpp7-x2x2-2mjf) — WP_Query SQLインジェクション |
| 発見者 | Adam Kues at Assetnote / Searchlight Cyber |
| ニックネーム | "WP2Shell" |
【重要】CVSSスコアの差異について:
- WPScan採点: 9.8 (Critical) — CVE-2026-60137との連鎖RCEを考慮した総合評価
- CISA-ADP採点: 7.5 (High) — バッチルート混同単体の評価(SQLi連鎖不含)
- Rapid7: 7.5 — バッチルート混同単体
これは連鎖攻撃の総合評価と単体脆弱性の評価の違いである。
影響を受けるソフトウェアおよびバージョン
| バージョンブランチ | 影響範囲 | 修正バージョン | 影響を受ける脆弱性 |
|---|---|---|---|
| WordPress 6.9.x | 6.9.0 – 6.9.4 | 6.9.5 | CVE-2026-63030 + CVE-2026-60137 (連鎖RCE) |
| WordPress 7.0.x | 7.0.0 – 7.0.1 | 7.0.2 | CVE-2026-63030 + CVE-2026-60137 (連鎖RCE) |
| WordPress 7.1 beta | 7.1 beta1 | 7.1 beta2 | CVE-2026-63030 + CVE-2026-60137 (連鎖RCE) |
| WordPress < 6.9 | — | — | 影響なし(バッチルート混同は6.9で導入) |
- CPE:
cpe:2.3:a:wordpress:wordpress:*:*:*:*:*:*:*:*(6.9.0 – 7.0.1)
技術詳細
脆弱性の概要
CVE-2026-63030は、WordPress 6.9で導入されたREST APIバッチエンドポイント(/wp-json/batch/v1)における「ルート混同(route confusion)」の脆弱性である。
バッチ処理の検証ループにおいて、不正なpathを含むサブスクリプトがWP_Errorとして処理される際、$matches配列への追加が省略された。これにより、$matches配列と$validation配列のインデックスがズレ、あるサブスクリプトのリクエストが別のサブスクリプトのルートハンドラで実行される状態が発生する。
単独では「認証バイパス」ではなく「ルート混同」だが、CVE-2026-60137(author__not_inのSQLi)と連鎖することで、認証なしのRemote Code Executionに至る。
根本原因
脆弱なコードは wp-includes/rest-api/class-wp-rest-server.php の serve_batch_request_v1() メソッド内に存在した。
❌ 脆弱な実装 (コミット fa72c12 以前のコード)
バッチ検証ループの制御フロー:
// バッチ検証ループ
foreach ( $requests as $i => $single_request ) {
if ( is_wp_error( $single_request ) ) {
$has_error = true;
// ⚠️ $validation にのみ追加 — $matches には追加されない!
$validation[] = $single_request;
continue;
}
// ... ルートマッチング処理 ...
$matches[] = $handler;
$validation[] = $validation_result;
}
インデックスズレの発生メカニズム:
requests: [error, request A, request B]
validation: [error, result A, result B]
matches: [match A, match B]
↑ index 0が欠落 → indexが1つズレる
実行ループでは $matches[$i] と $validation[$i] を参照するため:
i=1のとき:request Aがmatch B(本来はrequest B用のハンドラ)で実行されるi=2のとき:request Bが配列外参照(または別のハンドラ)で実行される
✅ 修正後の実装 (コミット fa72c12879fbfda17d450fc1fd919f698f549f4d)
if ( is_wp_error( $single_request ) ) {
$has_error = true;
// ✅ $matches にもダミーエントリーを追加してインデックスを維持
$matches[] = $single_request;
$validation[] = $single_request;
continue;
}
追加の防御層:
rest_api_loaded() と WP_REST_Server::serve_request() にも is_dispatching() チェックが追加され、バッチ処理中に新たなRESTサイクルが開始されることを防ぐ。
// rest_api_loaded()
if ( isset( $GLOBALS['wp_rest_server'] )
&& $GLOBALS['wp_rest_server'] instanceof WP_REST_Server
&& $GLOBALS['wp_rest_server']->is_dispatching()
) {
return;
}
// WP_REST_Server::serve_request()
if ( $this->is_dispatching() ) {
return false;
}
修正コミット詳細
| 項目 | 内容 |
|---|---|
| 修正コミット | fa72c12879fbfda17d450fc1fd919f698f549f4d |
| コミットメッセージ | "REST API: sub-requests must always use dispatch." |
| 変更ファイル数 | 2ファイル |
| 変更ファイル | wp-includes/rest-api.php, wp-includes/rest-api/class-wp-rest-server.php |
| 行数変更 | +27 行追加 |
| 新規関数 | WP_REST_Server::is_dispatching() |
RCE連鎖の仕組み
47Cid/wp2shell-lab の分析に基づく完全な連鎖フロー:
[攻撃者] → POST /wp-json/batch/v1
↓
serve_batch_request_v1() — Loop 1 (validate)
↓
[0] "http://:" → wp_parse_url fails → WP_Error (matchesに追加されない)
[1] POST /wp/v2/posts → match: posts_handler
[2] POST /batch/v1 → match: batch_handler
↓
$validation: [error, OK(posts), OK(batch)]
$matches: [posts_handler, batch_handler] ← index 0欠落
↓
serve_batch_request_v1() — Loop 2 (dispatch)
↓
i=0: error → skip
i=1: POST /posts → $matches[1] = batch_handler
→ postsリクエストのbodyがネストされたバッチとして処理される
↓
ネストバッチ内のLoop 1 (validate):
[0] "http://:" → WP_Error
[1] POST /wp/v2/categories → match: categories_handler
[2] GET /wp/v2/posts → match: posts_handler
↓
ネストバッチ内のLoop 2 (dispatch):
i=1: POST /categories → $matches[1] = posts_handler
→ categoriesリクエストがpostsのget_items()で処理される
→ author_exclude が categories スキーマにない → サニタイズされない
→ postsが author_exclude → WP_Query::author__not_in にマッピング
↓
WP_Query::author__not_in — CVE-2026-60137 (SQLi)
↓ スカラー値が直接SQLに埋め込まれる
[MySQL] → SQLインジェクション実行
↓
管理者パスワードハッシュ窃取 → クラック → 管理者ログイン
↓
プラグインアップロード → RCE
重要な技術的ポイント:
- バッチエンドポイントはWordPress 5.6(2020年11月)から存在するが、ルート混同は6.9(2025年12月)で導入
- Cloudflareの分析によれば、永続オブジェクトキャッシュが無効な環境でRCEパスに到達可能(デフォルト設定)
respond_to_request()は依然としてpermission_callbackを呼び出すため、この脆弱性は「認証バイパス」ではなく「ルート混同」— 公開読み取り可能なエンドポイント(postsのviewコンテキスト)を経由してSQLiに到達する
攻撃フロー
[攻撃者] → POST /wp-json/batch/v1
↓
[REST API Batch Endpoint] — CVE-2026-63030 (ルート混同)
↓ インデックスズレによりpostsリクエストがbatch_handlerで処理
[ネストバッチ処理] → categoriesリクエストがposts_handlerで処理
↓ author_excludeパラメータがサニタイズされずWP_Queryに到達
[WP_Query::author__not_in] — CVE-2026-60137 (SQLi)
↓ スカラー値が直接SQLクエリに埋め込まれる
[MySQL] → 管理者パスワードハッシュ返却
↓ ハッシュクラック
[管理者ログイン] → プラグインアップロードでPHP配置
↓
[RCE] — 任意のOSコマンド実行
トリガー条件
| 条件 | 詳細 |
|---|---|
| バージョン | 6.9.0 – 7.0.1 |
| 認証 | 不要 (匿名で到達可能) |
| プラグイン | 不要 (Coreのみで成立) |
| 永続オブジェクトキャッシュ | 無効な環境で exploitation が容易(Cloudflare分析) |
| REST API | 有効である必要あり(デフォルトで有効) |
PoC/Exploitの状況
| 項目 | 状況 |
|---|---|
| 公開PoC | あり — SQLi検証PoCが複数公開済み、完全RCEチェーンは未公開 |
| 教育用ラボ | あり — 47Cid/wp2shell-lab (root cause analysis + Docker lab) |
| PoCリポジトリ | Icex0/wp2shell-poc, Senanfurkan/wordpress-cve-2026-63030, attackercan/wp2shell-poc2 |
| Exploit成熟度 | PoC (SQLi確認済み) → 完全RCEチェーンは未公開 |
| 実利用 | PatchStackが2026-07-17に攻撃を観測報告(詳細不明) |
| Searchlight Checker | wp2shell.com — 脆弱性チェック用公開ツール |
⚠️ 注意: SQLiコンポーネントのPoCは公開・検証済み。完全RCE(ハッシュクラック→ログイン→プラグインアップロード)の完全なエクスプロイトコードはSearchlightによって公開されていないが、OpenSourceの性質上、パッチリバースエンジニアリングによる再現は時間の問題と予測される。
実被害・インシデント
- 2026-07-17 19:00 ET頃、PatchStackがCVE-2026-63030を標的とした攻撃を観測報告(観測内容の詳細は公開されていない)
- 開示時点では大規模な攻撃の報告はなかった
- WordPress.orgは影響を受けるサイトに対して強制自動アップデートを有効化した
- Searchlight Cyberは技術詳細を公開 withheld し、防御側にパッチ適用の時間を与えた
検出方法
ブラックボックステスト
バッチエンドポイント到達性確認
# テストA: 標準RESTパス
curl -sX POST "https://target.com/wp-json/batch/v1" \
-H "Content-Type: application/json" \
-d '{"requests":[]}'
# 期待応答: {"code":"rest_missing_callback_param","message":...}
# テストB: クエリパラメータパス
curl -sX POST "https://target.com/?rest_route=/batch/v1" \
-H "Content-Type: application/json" \
-d '{"requests":[]}'
バージョン確認
curl -sL "https://target.com/" | grep -oP 'content="WordPress [^"]*"'
# 6.9.0 – 6.9.4 または 7.0.0 – 7.0.1 → 影響あり
WAFルール (Cloudflare)
| ルール説明 | Managed Ruleset ID | Free Ruleset ID | デフォルトアクション |
|---|---|---|---|
| WordPress - Unauthenticated RCE | 7dfb2bd4708d4b88b9911dc0550664b6 |
ebd3f2df15c74ddcbf6220c9b5ec246a |
Block |
ホワイトボックステスト
修正確認
# is_dispatching() チェックの存在確認
grep -n "is_dispatching" wp-includes/rest-api.php
grep -n "is_dispatching" wp-includes/rest-api/class-wp-rest-server.php
# $matches[] = $single_request の存在確認(serve_batch_request_v1内)
grep -n 'matches\[\].*single_request' wp-includes/rest-api/class-wp-rest-server.php
対策
恒久的対策
| 現在のバージョン | 推奨アクション | 修正バージョン |
|---|---|---|
| 6.9.x | 6.9.5に更新 | 6.9.5 |
| 7.0.x | 7.0.2に更新 | 7.0.2 |
| 7.1 beta1 | 7.1 beta2に更新 | 7.1 beta2 |
- WordPressダッシュボード → 更新 → 「今すぐ更新」をクリック
- WP-CLI:
wp core update - 影響を受けるサイトには強制自動アップデートが既に有効化されている
暫定対策・軽減策
-
REST APIバッチエンドポイントのブロック:
- WAFで
/wp-json/batch/v1と?rest_route=/batch/v1へのアクセスをブロック - プラグイン「Disable WP REST API」で匿名アクセスを制限
- mu-プラグインでREST batchルートの認証を必須化
- WAFで
-
Cloudflare WAF:
- 2026-07-17 17:03 UTCに新ルールが全プランに自動デプロイ済み
- Managed Rules / Free Ruleset の両方で新ルールが有効か確認
-
Wordfence:
- Wordfence Premium/Care/Response: 2026-07-17にファイアウォールルール配信済み
- Wordfence Free: 2026-08-16に配信予定
修正パッチ詳細
ルート混同修正
コミット: fa72c12879fbfda17d450fc1fd919f698f549f4d
ファイル: wp-includes/rest-api/class-wp-rest-server.php, wp-includes/rest-api.php
変更内容:
serve_batch_request_v1(): WP_Error発生時に$matches[] = $single_requestを追加し、インデックスの整合性を維持rest_api_loaded(): REST dispatch実行中の場合はrest_routeの処理をショートサーキットWP_REST_Server::serve_request():is_dispatching()中は新たなRESTサイクルの開始を拒否WP_REST_Server::is_dispatching(): 新規メソッド — dispatch状態を追跡
再現環境
教育用ラボ環境が公開されている:
- 47Cid/wp2shell-lab — Dockerベースの教育的PoC + root cause analysis
- ZephrFish/wp2shell-scanner — 非破壊スキャナー
VulnCheckの評価によれば、RCEは以下の多段ステップを要する:
- バッチエンドポイント経由でルート混同トリガー
- SQLi実行(author__not_in経由)
- 管理者パスワードハッシュのダンプとクラック
- 管理者ログイン
- プラグインアップロードによるRCE
参考資料
公式情報源
- WordPress 7.0.2 Release Announcement
- GHSA-ff9f-jf42-662q (CVE-2026-63030)
- NVD — CVE-2026-63030
- CVE.org Record
技術分析
- Beazley Security — "WP2Shell" Advisory (BSL-A1193)
- VulnCheck — WP2Shell Vulnerabilities
- Cloudflare WAF Protection
- Wordfence PSA
- Searchlight Cyber — wp2shell Advisory
- Rapid7 — CVE-2026-63030 Analysis
- SOCRadar — CISO FAQ
- Aikido — wp2shell Analysis
修正コミット
PoC/ラボ
- 47Cid/wp2shell-lab — 教育的PoC + Docker lab
- ZephrFish/wp2shell-scanner — 非破壊スキャナー
- Icex0/wp2shell-poc
- Senanfurkan/wordpress-cve-2026-63030 — Detection PoC
- attackercan/wp2shell-poc2
- Searchlight wp2shell Checker
関連ファイル
変更履歴
| 日付 | 変更内容 |
|---|---|
| 2026-07-19 | 初版作成 — NVD, GHSA, Beazley, VulnCheck, Rapid7, Cloudflare, Wordfence, Searchlight, SOCRadar, Aikido, 47Cid/wp2shell-labの情報を統合 |
脆弱性情報(NVD)
- 深刻度: 緊急(CVSS 9.8)
- CVSSベクター:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - CWE: CWE-436
- EPSS: 38.60%(上位 1.6%)
影響を受けるバージョン:
- Wordpress Wordpress: >= 6.9, < 6.9.5
- Wordpress Wordpress: >= 7.0, < 7.0.2
概要(日本語): WordPress 6.9.5 より前の 6.9.x および 7.0.2 より前の 7.0.x では、REST API のバッチエンドポイントにおける経路混乱の問題が存在します。この問題は、author__not_in WP_Query SQL インジェクション (CVE-2026-60137) と組み合わさることで、攻撃者による SQL インジェクションおよびリモートコード実行を可能にする可能性があります。
原文: WordPress 6.9.x before 6.9.5 and 7.0.x before 7.0.2 is affected by a REST API batch endpoint route confusion issue which, combined with the author__not_in WP_Query SQL Injection (CVE-2026-60137), could allow an attacker to perform SQL Injection and achieve Remote Code Execution.
VulnCheck KEV
- 製品: WordPress Core
- CISA KEV 掲載: ✅ あり
- ランサムウェア悪用: Unknown
PoC / Exploit
- initial-access: GitHub(Icex0/wp2shell-poc) / VulnCheck XDB
- initial-access: GitHub(attackercan/wp2shell-poc2) / VulnCheck XDB
- denial-of-service: GitHub(Senanfurkan/wordpress-cve-2026-63030) / VulnCheck XDB
- info-leak: GitHub(tcyph3r/wp2shell-cve-2026-63030-root-cause) / VulnCheck XDB
- initial-access: GitHub(dinosn/wp2shell-lab) / VulnCheck XDB
- initial-access: GitHub(47Cid/wp2shell-lab) / VulnCheck XDB
- initial-access: GitHub(Lutfifakee-Project/wp2shell) / VulnCheck XDB
- info-leak: GitHub(ekomsSavior/wp2shell) / VulnCheck XDB
- info-leak: GitHub(NULL200OK/WP2Shell) / VulnCheck XDB
- info-leak: GitHub(4minx/CVE-2026-63030) / VulnCheck XDB
- initial-access: GitHub(mverschu/CVE-2026-63030) / VulnCheck XDB
- initial-access: GitHub(0xsha/wp2shell) / VulnCheck XDB
- info-leak: GitHub(J4ck3LSyN-Gen2/CVE-2026-63030-wp2r00t) / VulnCheck XDB
- info-leak: GitHub(gbrsh/CVE-2026-63030) / VulnCheck XDB
- initial-access: GitHub(0xBlackash/CVE-2026-63030) / VulnCheck XDB
- initial-access: GitHub(h4cd0c/wp2shell) / VulnCheck XDB
- info-leak: GitHub(mrx-arafat/CVE-2026-63030-POC) / VulnCheck XDB
- initial-access: GitHub(0xWhoknows/wp2shell) / VulnCheck XDB
- initial-access: GitHub(yoerivegt/wp2shell-poc) / VulnCheck XDB
- initial-access: GitHub(securelayer7/WordPresShell) / VulnCheck XDB
- initial-access: GitHub(fullhunt/wp2shell-scan) / VulnCheck XDB
- initial-access: GitHub(ChiefYoru/CVE-2026-63030_PoC) / VulnCheck XDB
- initial-access: GitHub(JohenLastGen-JLG/wp2shell) / VulnCheck XDB
- initial-access: GitHub(mhtsec/CVE-2026-63030) / VulnCheck XDB
- initial-access: GitHub(c0gnit00/Wp2Shell) / VulnCheck XDB
- initial-access: GitHub(ikow/wp2shell) / VulnCheck XDB
- initial-access: GitHub(bahartanir/wp2shell-scanner) / VulnCheck XDB
- info-leak: GitHub(0xh7ml/CVE-2026-63030) / VulnCheck XDB
- initial-access: GitHub(4B3R4M4-607D/CVE-2026-63030-POC) / VulnCheck XDB
- initial-access: GitHub(hidden-investigations/wp2shell-scanner) / VulnCheck XDB
- initial-access: GitHub(ZenithGenius/wordpress-batch-rce-lab) / VulnCheck XDB
- initial-access: GitHub(Crypto-Cat/wp2shell) / VulnCheck XDB
- info-leak: GitHub(joaovicdev/EXPLOIT-CVE-2026-63030) / VulnCheck XDB
- info-leak: GitHub(SentinelXofficial/sxwp2shell) / VulnCheck XDB
- info-leak: GitHub(ASYquan/wp2shell-cf-WAF-bypass) / VulnCheck XDB
- info-leak: GitHub(lucifer0xf/wp2shell-Wordpress-TOWN) / VulnCheck XDB
- initial-access: GitHub(Ch4120N/CVE-2026-63030) / VulnCheck XDB
- initial-access: GitHub(Colere-Sys/wp2shell-poc) / VulnCheck XDB
- initial-access: GitHub(Bhanunamikaze/WP2Shell-CVE-2026-63030-POC) / VulnCheck XDB
- initial-access: GitHub(mcipekci/wp2shell) / VulnCheck XDB
悪用事例
参考リンク
- github.com
Vendor Advisory - wordpress.org
Release Notes - www.cisa.gov
US Government Resource