Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
phpmyadmin-vqb-xss — phpMyAdmin 5.2.3 - High - Remote - XSS - Designer Visual Query Builder | Kitploit
Tools/GitHubGitHub/abraxas/phpmyadmin-vqb-xss
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLabs & Practice
GitHubabraxas/phpmyadmin-vqb-xss

phpmyadmin-vqb-xss

phpMyAdmin 5.2.3 - High - Remote - XSS - Designer Visual Query Builder

View Repository
4 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Abraxas Labs - phpmyadmin-vqb-xss

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  phpmyadmin-vqb-xss

phpmyadmin-vqb-xss

Class: Stored XSS Reach: Remote

phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin

js/src/designer/history.js builds visual-query history with innerHTML. Column names go through $('<div/>').text(...).html(). Table names do not. TableName still allows < and >. A low-privilege account with CREATE TABLE on a shared database plants an HTML identifier. When a higher-privilege user opens Designer, getTableName() is sitting on the page and DesignerHistory.display() writes it into #ab.

A stored XSS in the phpMyAdmin origin. Same class as PMASA-2025-1, different feature. Check-tables headings were escaped. This path was not.

IDno CVE yet
ClassStored XSS
ReachRemote (authenticated CREATE TABLE; victim opens Designer)
CWECWE-79
CVSSHigh: 8.0 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N
ProductphpMyAdmin
Affected5.2.3 tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
Authauthenticated. Attacker needs CREATE TABLE on a database the victim opens in Designer
LicenseGNU Affero GPL v3.0
Lab127.0.0.1 only

What an attacker can do

Plant an HTML table name, then wait for a higher-privilege user to open Designer on that database and render visual-query history.

PrivilegeMethod / sinkRecon / integrity / availabilityLab-proven or inferred
Inject markup into the phpMyAdmin originDesignerHistory.display() concatenates getTab() into #ab innerHTMLIntegrity of the victim originLab-proven. Live history.js on phpmyadmin:5.2.3. <h3> contained <i id="pma-vqb">
Break out of a designer table_name attributedatabase_tables.twig small_tab_pref_1 uses designerTable.getTableName()Recon of the raw MySQL name in the Designer DOMLab-proven readable as the raw identifier
Read the victim session cookie and CSRF tokenSame-origin script once history rendersRecon of the victim PMA sessionInferred from stored XSS in the PMA origin. This lab uses an <i> marker, not a script
Run SQL, manage users, export, as the victim MySQL accountToken-backed POST /sql, /server/privileges, exportIntegrity of whatever that MySQL account can touchInferred. Same impact class as PMASA-2025-1
Change 2FA / userconfigPOST /config/set as the victimIntegrity of the victim preference storeInferred. Sibling leftover, not this lab

Closed on this leftover: unauthenticated access, OS RCE, and the VQB OK button path. .small_tab_pref_click_opt pre-escapes table_name and Twig autoescapes it again, so that click currently feeds entities into getTab(). That is not a fix of history.js. Column cells stay text-escaped (c<b id=pma-col>y, no <b id="pma-col"> node).

Same pin: WebAuthn CustomServer leftover.

How I found it

I pinned phpMyAdmin RELEASE_5_2_3. PMASA-2025-1/2/3 are already in 5.2.2. Designer still builds VQB history HTML by hand.

js/src/designer/history.js (shipped as 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 only checks non-empty, max 64, no trailing space. < and > are legal. MySQL accepts them in a quoted identifier.

templates/database/designer/database_tables.twig copies designerTable.getTableName() into table_name on .small_tab_pref_1. The VQB option cell uses a pre-escaped copy of the same name.

Wrong turns already recorded: treating the double-escaped option-button attribute as the fix (it is not - small_tab_pref_1 still exposes the raw name, and history.js is the sink); treating the column helper as covering table names; claiming unauthenticated XSS; a reverse shell. Theatre.

Lab

python3 phpmyadmin-vqb-xss-Abraxas-Labs.py
# or: cd lab && ./run.sh

Target only http://127.0.0.1:19250. Images phpmyadmin:5.2.3 and mysql:8.0. Compose project phpmyadmin-vqb-xss. Playwright Chromium in the poc service. Stack tears down after the run.

Two users, shared shareddb. Low-priv creator runs CREATE TABLE \tx` (`cy` INT). Higher-priv victimlogs into phpMyAdmin and opens Designer withquery=1. Live history.js is the copy from the container (h3-unescaped=yes, column helper present). Chromium calls DesignerHistory.display()with the table name fromgetTableName()` on the page.

Result: #ab h3.tiger innerHTML is <a href="#">t<i id="pma-vqb">x</i></a>. Column td text is c<b id=pma-col>y with no b#pma-col node.

SUCCESS phpmyadmin-vqb-xss h3-markup=yes col-escaped=yes how=live PMA-VQB-XSS-WITNESS

The fix

Escape getTab() with $('<div/>').text(temp).html() or Functions.escapeHtml before concatenating into the <h3>. Do not rely on Twig double-encoding of one attribute. Keep the column-name helper as the model.

References

  • github.com/phpmyadmin/phpmyadmin tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
  • js/src/designer/history.js
  • libraries/classes/Dbal/TableName.php
  • Nearby patched (not this path): PMASA-2025-1 Check-tables headings
  • Same pin: PMA-5.2.3-WebAuthn-2FA
  • CWE-79

License

GNU Affero GPL v3.0. See LICENSE. Loopback lab only. No warranty.

Download Tool