
phpMyAdmin 5.2.3 - 高 - リモート - XSS - Designer Visual Query Builder
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-vqb-xss
クラス: 格納型XSS 到達範囲: リモート
phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin
js/src/designer/history.js はビジュアルクエリ履歴を innerHTML で構築する。カラム名は $('<div/>').text(...).html() を経由する。テーブル名は経由しない。TableName は依然として < と > を許可している。共有データベース上で CREATE TABLE 権限を持つ低権限アカウントが HTML 識別子を仕込む。高権限ユーザーが Designer を開くと、getTableName() がページ上に存在し、DesignerHistory.display() がそれを #ab に書き込む。
phpMyAdmin オリジンにおける格納型XSS。PMASA-2025-1 と同クラスだが、機能が異なる。Check-tables の見出しはエスケープされていた。この経路はされていなかった。
| ID | CVE 未採番 |
| クラス | 格納型XSS |
| 到達範囲 | リモート (認証済み CREATE TABLE、被害者が Designer を開く) |
| CWE | CWE-79 |
| CVSS | High: 8.0 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N |
| 製品 | phpMyAdmin |
| 影響バージョン | 5.2.3 タグ RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| 認証 | 認証済み。攻撃者は被害者が Designer で開くデータベースに対する CREATE TABLE 権限が必要 |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
HTML テーブル名を仕込み、高権限ユーザーがそのデータベースで Designer を開き、ビジュアルクエリ履歴をレンダリングするのを待つ。
| 権限 | メソッド / シンク | 偵察 / 完全性 / 可用性 | ラボ実証または推測 |
|---|---|---|---|
| phpMyAdmin オリジンへのマークアップ注入 | DesignerHistory.display() が getTab() を #ab innerHTML に連結 | 被害者オリジンの完全性 | ラボ実証済み。phpmyadmin:5.2.3 上のライブ history.js。<h3> に <i id="pma-vqb"> が含まれた |
designer の table_name 属性からの脱出 | database_tables.twig の small_tab_pref_1 が designerTable.getTableName() を使用 | Designer DOM 内の生の MySQL 名の偵察 | ラボ実証済み、生の識別子として読み取り可能 |
被害者のセッション Cookie と CSRF token の読み取り | 履歴レンダリング後の同一オリジンスクリプト | 被害者 PMA セッションの偵察 | PMA オリジンにおける格納型XSSからの推測。このラボではスクリプトではなく <i> マーカーを使用 |
| 被害者の MySQL アカウントとして SQL 実行、ユーザー管理、エクスポート | トークン付き POST /sql、/server/privileges、export | その MySQL アカウントが触れられるものの完全性 | 推測。PMASA-2025-1 と同クラスの影響 |
| 2FA / userconfig の変更 | 被害者として POST /config/set | 被害者設定ストアの完全性 | 推測。同種の残存問題であり、このラボではない |
この残存問題で除外されたもの: 未認証アクセス、OS RCE、VQB の OK ボタン経路。.small_tab_pref_click_opt は table_name を事前エスケープし、Twig がさらに自動エスケープするため、そのクリックは現在 getTab() にエンティティを渡している。これは history.js の修正ではない。カラムセルはテキストエスケープされたままである (c<b id=pma-col>y、<b id="pma-col"> ノードはなし)。
同じピン: WebAuthn CustomServer の残存問題。
phpMyAdmin RELEASE_5_2_3 をピン留めした。PMASA-2025-1/2/3 はすでに 5.2.2 に含まれている。Designer は依然として VQB 履歴 HTML を手作業で構築している。
js/src/designer/history.js (js/dist/designer/history.js として出荷):
temp = historyArray[i].getTab();
str += '<h3 class="tiger"><a href="#">' + temp + '</a></h3>';
// ...
'<td width="175" style="padding-left: 5px">' + $('<div/>').text(historyArray[i].getColumnName()).html() + '<td>';
libraries/classes/Dbal/TableName.php は空でないこと、最大 64 文字、末尾スペースなしのみをチェックする。< と > は合法である。MySQL はクォートされた識別子内でこれらを受け入れる。
templates/database/designer/database_tables.twig は designerTable.getTableName() を .small_tab_pref_1 の table_name にコピーする。VQB オプションセルは同じ名前の事前エスケープされたコピーを使用する。
すでに記録済みの誤った道: 二重エスケープされたオプションボタン属性を修正とみなすこと (そうではない - small_tab_pref_1 は依然として生の名前を露出しており、history.js がシンクである)、カラムヘルパーがテーブル名をカバーしているとみなすこと、未認証 XSS の主張、リバースシェル。茶番である。
python3 phpmyadmin-vqb-xss-Abraxas-Labs.py
# or: cd lab && ./run.sh
対象は http://127.0.0.1:19250 のみ。イメージは phpmyadmin:5.2.3 と mysql:8.0。Compose プロジェクトは phpmyadmin-vqb-xss。poc サービス内の Playwright Chromium。実行後にスタックは破棄される。
2 ユーザー、共有 shareddb。低権限の creator が CREATE TABLE \tx` (`cy` INT)を実行する。高権限のvictim が phpMyAdmin にログインし、query=1で Designer を開く。ライブhistory.js はコンテナからのコピーである (h3-unescaped=yes、カラムヘルパーあり)。Chromium はページ上の getTableName()から取得したテーブル名でDesignerHistory.display()` を呼び出す。
結果: #ab h3.tiger の innerHTML は <a href="#">t<i id="pma-vqb">x</i></a>。カラム td のテキストは c<b id=pma-col>y で、b#pma-col ノードは存在しない。
SUCCESS phpmyadmin-vqb-xss h3-markup=yes col-escaped=yes how=live PMA-VQB-XSS-WITNESS
getTab() を <h3> に連結する前に $('<div/>').text(temp).html() または Functions.escapeHtml でエスケープする。1 つの属性に対する Twig の二重エンコードに依存しないこと。カラム名ヘルパーをモデルとして維持する。
962857e4f63d42e38f11ff4d63f5e722018add76)js/src/designer/history.jslibraries/classes/Dbal/TableName.phpGNU Affero GPL v3.0。LICENSE を参照。ループバックラボのみ。無保証。